【发布时间】:2015-08-03 16:07:49
【问题描述】:
我正在阅读的一本初学者的 C 书籍让我对 getchar() 和缓冲区顺序(尤其是与换行符有关)感到困惑。它说,
摆脱 Enter 键是所有 C 初学者都必须面对的问题。考虑以下程序段:
printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();
您会认为如果用户键入
GT,G将进入变量firstInit,而T将进入lastInit,但事实并非如此。第一个getchar()直到用户按 Enter 才完成,因为G将进入缓冲区。只有当用户按下 Enter 时,G才会离开缓冲区并进入程序——但是 然后 Enter 仍然 在缓冲区中!因此,第二个getchar()将该 Enter (\n) 发送到lastInit。T仍然留给后续的getchar()(如果有的话)。
首先,我不明白作者对为什么\n 转到lastInit 而不是T 的解释。我猜是因为我将缓冲区可视化为“先进先出”。无论哪种方式,我都不明白作者呈现的顺序背后的逻辑——如果用户输入G,然后输入T,然后输入,G 是如何被第一个getchar() 捕获的, Enter(换行符)被第二个getchar()捕获,T被第三个getchar()捕获?令人费解。
其次,我自己尝试了这个(Ubuntu 14.04 在 Windows 8.1 下的 VMWare 上运行,文本编辑器 Code::Blocks,编译器 gcc),我得到了作者所说的确切常识结果 不发生!:G 转到 firstInit,T 转到 lastInit。这是我的代码:
#include <stdio.h>
main()
{
char firstInit;
char lastInit;
printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();
printf("Your first initial is '%c' and ", firstInit);
printf("your last initial is '%c'.", lastInit);
return 0;
}
输出是:
What are your two initials?GTYour first initial is 'G' and your last initial is 'T'.
我还创建了一个后续程序,它似乎确认换行符最后从缓冲区中出来:
main()
{
char firstInit;
char lastInit;
int newline;
printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();
newline = getchar();
printf("Your first initial is '%c' and ", firstInit);
printf("your last initial is '%c'.", lastInit);
printf("\nNewline, ASCII %d, comes next.", newline);
return 0;
}
输出是:
What are your two initials?GTYour first initial is 'G' and your last initial is 'T'.Newline, ASCII 10, comes next.
所以我在这里遗漏了什么还是作者错了? (或者这个编译器依赖——即使作者没有这么说)?
书籍:C Programming Absolute Beginner's Guide,第 3 版,Greg Perry,©2014,Ubuntu 14.04,gcc 编译器版本 4.8.4
【问题讨论】:
-
尝试输入“G
T ”。 -
@AndrewHenle 我只能在程序终止之前输入 G
。在这种情况下 firstInit 捕获 G 而 lastInit 捕获换行符,这是我所期望的。 -
只需输入“GT
”。 BTW main定义不正确,应该是int main(void)。 -
是的。你几乎证实你的书是错的。不,我不知道它在任何上下文中是正确的,但是很难证明它在作者写的时候是不正确的。
-
@WeatherVane 嗨,正如我在问题中解释的那样,我确实输入了 GT
,得到的结果与作者所说的不同,这就是我问这个问题的原因。关于 main 的定义不正确,我是一个初学者,只是按照书中的格式(他没有说任何关于 int main(void) 的内容。谢谢。