关于getchar()与输入缓冲区的疑问:为何两次循环行为不同?
我编写了以下代码来熟悉getchar()函数,其中这段循环代码取自书籍:
while(ch != '\n' && ch != EOF) ch = getchar();
令我困惑的是,代码中第二次使用getchar()的while循环会触发程序请求输入,而上述这段循环却不会。我的输入是字符数超过MAX_SIZE的行,这是否是因为输入缓冲区中仍残留数据?以下是我的完整代码:
#include <stdio.h> #include <string.h> #define MAX_SIZE 10 int main () { int ch = 0, i = 0; char array[MAX_SIZE] = {0}; while(1) { i = 0; while((ch = getchar()) != EOF && ch != '\n' && i < MAX_SIZE - 1) { array[i++] = ch; } array[i] = '\0'; while(ch != '\n' && ch != EOF) ch = getchar(); printf("%s\n",array); for (int i = 0; i < strlen(array) + 1; i++) printf("[%d]%d\n",i, array[i]); } }
你的猜测完全正确,核心原因就是输入缓冲区中残留的数据,具体分两种情况解释:
当输入行长度超过
MAX_SIZE-1时:
第一个while循环会读取前MAX_SIZE-1个字符存入数组,此时变量ch会停留在缓冲区里的下一个字符(既不是EOF也不是换行符\n)。接下来的第二个while循环会不断调用getchar()读取缓冲区里剩余的所有字符,直到读到换行符或EOF才停止——这个过程不需要程序请求新输入,因为缓冲区里还有未读取的数据。当输入行长度≤
MAX_SIZE-1时:
第一个while循环会一直读到换行符或EOF才终止,此时ch的值是\n或EOF,第二个while循环的条件ch != '\n' && ch != EOF不成立,循环直接跳过。只有当下一轮循环的第一个getchar()执行时,因为缓冲区已经空了,才会触发程序请求输入。
举个具体例子:
如果输入1234567890abc\n(长度远大于MAX_SIZE-1=9),第一个循环读取前9个字符123456789存入数组,此时ch是字符0;第二个循环会依次读取0、a、b、c,直到读到换行符\n,清空缓冲区后循环结束,全程不需要新输入。
如果输入123456789\n(刚好9个字符),第一个循环读完后ch是\n,第二个循环直接跳过;程序打印完内容进入下一轮,此时缓冲区为空,下一个getchar()就会触发输入请求。
内容的提问来源于stack exchange,提问作者Peter Kirsch

