getchar() 和缓冲区顺序
getchar() and buffer order
我正在阅读的一本初学者 C 语言书籍让我对 getchar() 和缓冲区顺序(尤其是与换行相关)感到困惑。它说,
Getting rid of the Enter keypress is a problem that all beginning C programmers must face. Consider the following segment of a program:
printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();
You would think that if the user typed GT
, the G
would go in the variable firstInit
and the T
would go in lastInit
, but that's not what happens. The first getchar()
doesn't finish until the user presses Enter because the G
was going to the buffer. Only when the user presses Enter does the G
leave the buffer and go to the program—but then the Enter is still on the buffer! Therefore, the second getchar()
sends that Enter (\n
) to lastInit
. The T
is still left for a subsequent getchar()
(if there is one).
首先,我不明白作者关于为什么 \n
去 lastInit
而不是 T
的解释。我猜是因为我将缓冲区可视化为“先进先出”。无论哪种方式,我都不明白作者提出的顺序背后的逻辑——如果用户输入 G
,然后输入 T
,然后输入,G
是如何被捕获的第一个 getchar()
,Enter(换行符)被第二个 getchar()
捕获,T
被第三个 getchar()
捕获?莫名其妙。
其次,我自己尝试了这个(Ubuntu 14.04 运行 on VMWare under Windows 8.1,文本编辑器 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?
GT
Your 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?
GT
Your first initial is 'G' and your last initial is 'T'.
Newline, ASCII 10, comes next.
我是不是遗漏了什么,还是作者错了? (或者这是否依赖于编译器——即使作者没有这么说)?
书籍:C 编程绝对初学者指南,第 3 版,Greg Perry,©2014,Ubuntu14.04,gcc 编译器版本 4.8.4
作者描述的是用户输入"G<enter>T<enter>"的场景。
这是一个不同的例子。对于每个输入的选项 1、2 或 3,菜单循环将迭代两次。
从 //while ( ( getchar ( ) != '\n')) {}
中删除注释 //
,缓冲区将在每次输入后被清除,菜单每次输入仅循环一次。
#include <stdio.h>
int main()
{
char *menu[] = { "1. first", "2. second", "3. third", "4. Exit"};
int choice = 0;
int each = 0;
do {
for ( each = 0; each < 4; each++) {
printf ( "%s\n", menu[each]);
}
printf ( "\tenter choice 1-4\n");
choice = getchar ( );
//clear the buffer
//while ( ( getchar ( ) != '\n')) {}
printf ( "you entered %d %c\n", choice, choice);
} while ( choice != '4');
return 0;
}
我正在阅读的一本初学者 C 语言书籍让我对 getchar() 和缓冲区顺序(尤其是与换行相关)感到困惑。它说,
Getting rid of the Enter keypress is a problem that all beginning C programmers must face. Consider the following segment of a program:
printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();
You would think that if the user typed
GT
, theG
would go in the variablefirstInit
and theT
would go inlastInit
, but that's not what happens. The firstgetchar()
doesn't finish until the user presses Enter because theG
was going to the buffer. Only when the user presses Enter does theG
leave the buffer and go to the program—but then the Enter is still on the buffer! Therefore, the secondgetchar()
sends that Enter (\n
) tolastInit
. TheT
is still left for a subsequentgetchar()
(if there is one).
首先,我不明白作者关于为什么 \n
去 lastInit
而不是 T
的解释。我猜是因为我将缓冲区可视化为“先进先出”。无论哪种方式,我都不明白作者提出的顺序背后的逻辑——如果用户输入 G
,然后输入 T
,然后输入,G
是如何被捕获的第一个 getchar()
,Enter(换行符)被第二个 getchar()
捕获,T
被第三个 getchar()
捕获?莫名其妙。
其次,我自己尝试了这个(Ubuntu 14.04 运行 on VMWare under Windows 8.1,文本编辑器 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?
GT
Your 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?
GT
Your first initial is 'G' and your last initial is 'T'.
Newline, ASCII 10, comes next.
我是不是遗漏了什么,还是作者错了? (或者这是否依赖于编译器——即使作者没有这么说)?
书籍:C 编程绝对初学者指南,第 3 版,Greg Perry,©2014,Ubuntu14.04,gcc 编译器版本 4.8.4
作者描述的是用户输入"G<enter>T<enter>"的场景。
这是一个不同的例子。对于每个输入的选项 1、2 或 3,菜单循环将迭代两次。
从 //while ( ( getchar ( ) != '\n')) {}
中删除注释 //
,缓冲区将在每次输入后被清除,菜单每次输入仅循环一次。
#include <stdio.h>
int main()
{
char *menu[] = { "1. first", "2. second", "3. third", "4. Exit"};
int choice = 0;
int each = 0;
do {
for ( each = 0; each < 4; each++) {
printf ( "%s\n", menu[each]);
}
printf ( "\tenter choice 1-4\n");
choice = getchar ( );
//clear the buffer
//while ( ( getchar ( ) != '\n')) {}
printf ( "you entered %d %c\n", choice, choice);
} while ( choice != '4');
return 0;
}