C - 获取字符函数清除 while 条件之外的输入缓冲区?



我了解到可以像这样清空输入缓冲区:

while((ch = getchar()) != EOF && ch != 'n');
if (ch == EOF) {
// oops
}

那么为什么我不能用以下行清空一个字符来清空缓冲区:

c = getchar();

此行将导致程序等待用户输入。上下文:

void strfuncs()
{
char name[50] = {0};
char lastname[50] = {0};
char c;
printf("Enter name...:");
fgets(name, 50, stdin);
printf("Enter last name...:");
fgets(lastname, 50, stdin);
c=getchar();
printf("Enter a character...:");
fgets(&c, 1, stdin);
printf("c: %c",c);
}
c = getchar();

如果有缓冲区,这确实会清空一个字符的缓冲区。但是,考虑到人类键入相对于计算机运行速度的速度,当执行该行时,缓冲区很可能为空。如果缓冲区为空getchar将等到它不为空。

while((ch = getchar()) != EOF && ch != 'n');

以上也不例外。大多数情况下,计算机将在getchar内等待缓冲区变为非空。

在正常模式下,当标准输入来自终端时,操作系统仅在收到换行符时将字符发送到程序的输入缓冲区,或者如果用户键入ctrl-D(在 *nixes 上,不确定 Windows 上的等效字符是什么)。循环实际上会在第一getchar()阻塞,直到您键入整行并按回车键。然后,它将尽可能快地循环旋转,消耗您键入的所有字符。这一切都发生在您按下回车键

char c;        // <<<< Wrong!
c = getchar();

这与问题无关,但getchar()的类型int.这很重要,因为EOF需要与可以输入的所有有效字符区分开来,并且在某些字符集中,char的每个可能值(在所有现代通用实现中为 0 到 255 或 -128 到 127)都是有效字符。

这种清空输入流的习惯用法仅在输入流中有字符要读取时才有效;否则getchar()将阻塞,等待输入。如果输入流中有字符,getchar()将读取其中一个字符。

fgets()函数保留换行符,因此在以这种方式获取一行输入后似乎没有必要清理输入流。但是,如果缓冲区不够大,则会留下字符。处理此问题的一种方法是检查输入缓冲区中的换行符,如果输入流不存在,则清理输入流。如果在输入缓冲区中找到换行符,通常会将其删除:

char buffer[1000];
puts("Enter a line:");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
perror("Error in fgets()");
exit(EXIT_FAILURE);
}
char *ch;
int c;
if ((ch = strchr(buffer, 'n')) == NULL) {
while ((c = getchar()) != 'n' && c != EOF) {
continue;
}
} else {
*ch = '';
}

请注意,应使用int变量来接收getchar()返回的值,以确保正确处理EOF

最新更新