在这里,我在接受的答案中看到了这个陈述:
大多数转换说明符都跳过前导空格,包括换行符但
%c不跳过.
对我来说,不清楚这种不同行为的基本原理,我会期待一个统一的(例如总是跳过或从不).
我用这样的一段C代码遇到了这种问题:
#include "stdio.h"
int main(void){
char ch;
int actualNum;
printf("Insert a number: ");
scanf("%d", &actualNum);
// getchar();
printf("Insert a character: ");
scanf("%c", &ch);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
交换两个scanf小号解决了问题,以及在(注释)getchar,否则'\n'该第一插入将由所述第二消耗scanf与%c.我在linux和windows上测试了gcc,行为是一样的:
gcc(GCC)4.7.2 20120921(Red Hat 4.7.2-2)
版权所有(C)2012 Free Software Foundation,Inc.
这是免费软件; 查看复制条件的来源.没有保修; 甚至不适用于适销性或特定用途的适用性.
所以我的问题是:为什么%d和%c行为不同WRT '\n'的scanf?
我正在测试我的概念证明原型处理XML模式,并围绕一个非常耗费内存的外部库构建树自动机(我已经获得了源代码),我想绘制"真正的峰值"(堆) )随着模式大小的增加,不同运行的内存消耗(使用的度量符合我的purpouse并且不影响问题),或者至少是它的合理近似值.
为了给出一个数量级,对于一个真正的峰值为100MB的运行(我测试它运行几次完全相同的输入/参数配置,强制jvm内存-Xmx和-Xms减少值,我得到Exception in线程"main"java.lang.OutOfMemoryError:GC开销限制超过 <100MB,具有稳定且可重复的结果)它占用大约1.1GB,这就是为什么获取实数对我来说非常重要,因为它们差别很大!
我花了最近10天在网上和stackoverflow中阅读问题,我实际知道的是:
System.gc()"建议"GC运行,不以任何方式强制它,因此不可能依赖它来检测内存使用峰值
通常建议的是计算对象占用(我看到了SizeOf项目,我尝试并且工作正常,即使它不符合我的需要),这对我来说是不可行的,因为由于创建了大量的内存分配很多收集(设置,列表和映射)迭代器在不同的方法中,被称为非常多次(对于我记得的10分钟,每个数百万次),因此检测所有涉及的对象将非常困难并执行总和(我用内存消耗图表调试了很多次运行而不能只识别一个瓶颈)
没有办法轻松获取方法的内存占用(表示为对象内存分配的峰值)
事实上,我自己经历过System.gc()调用不可靠(例如,由于GC被真正调用或未调用,因此在System.gc()之后读取不同的内存),但是当我按下JVisualVM或Jconsole中的"GC按钮",它永远不会运行GC或拒绝这样做.
所以我的问题是:调用他们的那个按钮的实现(我还没有尝试过,但是对于我现在所读到的,使用带有attach api的 jconsole.jar似乎是可行的)将不同于直接调用System.gc()从我的代码,从而解决我的问题?如果没有,你如何解释该按钮的"确定性行为"?
到目前为止,我给出了10个增加的模式大小的实际内存峰值的手动测试(对于这种测量,模式是从单个"复杂性参数"自动生成的)并且我绘制了预期的曲线,如果我将无法获得一个更好的解决方案我想将我的代码作为外部jar运行,-Xmx/-Xms等于略低于我对预期内存峰值的预测,捕获外部进程ErrorStream中的OutMemoryException并重新启动增加内存直到完成运行已完成.(如果天真的记忆预测不够健壮,我将应用适当的机器学习技术).我知道这不是一个优雅的解决方案,但在我的情况下(学术界),我可以花费一些额外的时间来进行这些测量.
系统信息(机器是Fedora 17,64位):
java版"1.7.0_04"Java(TM)SE运行时环境(版本1.7.0_04-b20)Java HotSpot(TM)64位服务器VM(版本23.0-b21,混合模式)
提前谢谢,亚历山德罗