我正在阅读一本初学者的C语言书,关于getchar()和缓冲区顺序(特别是与换行符有关)让我感到困惑。它说:
“摆脱回车键的按下是所有初学者C程序员必须面对的问题。考虑以下程序片段:”
你可能认为,如果用户键入了
首先,我不理解作者为什么要解释为什么
其次,我也尝试了一下(在Windows 8.1的VMware虚拟机上运行Ubuntu 14.04,使用Code::Blocks文本编辑器和gcc编译器),并且得到了与作者所说的看起来不合理的结果!
“摆脱回车键的按下是所有初学者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
。如果有后续的getchar()
,T
仍然会留下来。首先,我不理解作者为什么要解释为什么
\n
会发送给lastInit
,而不是T
。我猜是因为我将缓冲区视为“先进先出”的方式。不管怎样,我都不理解作者所呈现的顺序背后的逻辑——如果用户输入G
,然后是T
,最后是Enter键,为什么G
被第一个getchar()
捕获,Enter键(换行符)被第二个getchar()
捕获,而T
被第三个getchar()
捕获?令人困惑。其次,我也尝试了一下(在Windows 8.1的VMware虚拟机上运行Ubuntu 14.04,使用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;
}
输出结果为:
你的两个首字母是什么?
GT
你的第一个首字母是 'G',最后一个首字母是 '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;
}
输出结果如下:
你的两个首字母是什么?
GT
你的第一个首字母是'G',最后一个首字母是'T'。
接下来是换行符,ASCII码为10。
那么我是否漏掉了什么或者作者是错误的呢?(或者这取决于编译器,即使作者没有这样说)?
书籍:C Programming Absolute Beginner's Guide,第三版,Greg Perry,©2014,Ubuntu 14.04,gcc编译器版本4.8.4
main
定义不正确,应该是int main(void)
。 - Weather Vane