我的旧闻,原来发布在Spaces.live.com
来是在写一个水准测量的校验程序的,结果在处理用户界面时,我遇到相当不爽的问题——getchar()和printf()似乎在buf的问题上不能按照最好的思路协调。结果我的程序就在神经错乱中献出了最宝贵的生命。
来是在写一个水准测量的校验程序的,结果在处理用户界面时,我遇到相当不爽的问题——getchar()和printf()似乎在buf的问题上不能按照最好的思路协调。结果我的程序就在神经错乱中献出了最宝贵的生命。
一个向来都不在考虑之中的输入输出部分开始让我郁闷,疯狂和吃东西。奋战的两点的东西,结果让我第二天一整天的测量都是累得半死,而且要算大量的数据——这个一度让我差点要重测两天的路程。
根据K&R的解释,stdin和stdout是extern FILE
_iob[OPEN_MAX]的0和1入口,这个_iob[]由系统实现。同时stdin和stdout都是缓冲了的,buf的大小大概为1024(老
unix)或者4096(BSD)。由此我们可以得知,c =
getchar()的写法,c并非立刻得到值,而是当'/n'进入后或者buf满了后,缓冲区清空后得到的。我写了一个小程序:
int c, x;
sprintf(stderr, "%d", clock());
c = getchar();
x = c;
while(EOF != (c = getchar)) {
sprintf(stderr, "Sec %d", clock());if ( c != x) {sprintf(stderr, "sec %d", clock());fflush(NULL);putchar(c);fflush(NULL);sprintf(stderr, "sec %d", clock());}x = c;sprintf(stderr, "sec %d", clock());
}
然后你就可以大量的输入了,然后观察值得变化。很明显的,第一个输出值比第二个要早大概4的速度(我猜是ms),后面的值是很连续的,可见,又一个缓冲过程。但是大概每两个输出(或者4个)就会又一个时间的变化,我猜测是乱序执行或者是合并指令之类优化的杰作。
在comp.lang.c的历史文献里,有人指出printf()和getchar()在连用时,当顺序不同时,往往有不
同结果,或者程序对user的动作期待是不同的(比较了Linux和SGI后),并且建议在interactive类型的程序中使用strtod()之类
的函数从手工buf中读数("scanf/getchar sequence problem", Eric Sosman, Apri. 7th, 2005, 11:20 p.m.)。
另外,当scanf(...)后,用getchar(),结果会成为'/n',即无论是scanf()还是getchar()都需要的LR(ascii 0xA)还是会压入buf队列的。
宽字符部分:wchar_t c;然后再直接scanf("%c", &c);结果C会完整得存储GBK编码(也可能是Unicode 16)。
P.S. 我的malloc()莫名其妙的return NULL,而且是在一个极小的程序中,内存充足时发生的。