清除stdin缓冲区?

我正在编写一些代码并使用fgets来获取用户输入。 然后我在我的代码上写了一个循环来继续询问用户输入,直到用户打印退出。 但它第二次问,它写了“请输入你的输入”2次而不是1次,并没有等到我第一次输入。 所以,我用谷歌搜索它,发现stdin缓冲区已经填满,必须清除它。 我找到了这个解决方案

void dump_line(FILE * fp) { int ch; while ((ch = fgetc(fp)) != EOF && ch != '\n') { /* null body */; } } 

然后从main函数调用:

 dump_line(stdin); 

我很难理解它。 据我所知,它只是赋予“ch”fgetc(stdin)的值。我只是无法理解如何将fgetc(stdin)分配给“ch”清除缓冲区。 非常感谢您的帮助!

这是我用于输入用户输入的旧片段,如果我真的需要在纯C中使用它:

 int get_line(char *buffer, int bsize) { int ch, len; fgets(buffer, bsize, stdin); /* remove unwanted characters from the buffer */ buffer[strcspn(buffer, "\r\n")] = '\0'; len = strlen(buffer); /* clean input buffer if needed */ if(len == bsize - 1) while ((ch = getchar()) != '\n' && ch != EOF); return len; } 

它从stdin中检索bsize数量的字母并将它们存储到给定的缓冲区中。 stdin输入缓冲区中剩余的东西将被自动清理 。 它还从输入数据中删除换行符(\ r和\ n)。

函数返回成功读取的字符数。

它简单地为“ch”赋予fgetc(stdin)的值

调用fgetc会产生副作用 ,即从该文件流中读取和删除字符。

fgetc(stdin)分配给ch不是清除缓冲区的原因。 这是fgetc(stdin)的实际调用 。 每次调用(因此,循环的每次迭代)都会从stdin一个char。

这个怎么运作:

  1. 调用fgetc(stdin) ,并将结果赋给ch
  2. 如果ch不等于EOF'\n' ,请转到1。

当循环停止时,两个事情中的一个将是真的:要么你只是吃了标记当前行结束的字符(读:你现在在下一行),或者stdin是空的,你赢了’得到更多的输入。 (后者在交互式应用程序中是不常见的,但是当人们从其他地方将内容传输到您的应用程序时很常见。为此做好准备。)

fgetc()从缓冲区中获取一个字符。 此代码从缓冲区中读取字符,直到到达文件结尾或换行符。

这是相同的循环,但写的不同,也许这将解释它:

 void dump_line(FILE * fp) { /* dump a line from fp */ int ch; /* temporary storage for character */ while (1) { ch = fgetc(fp); /* read char from fp, this removes it from the stream */ if (ch == EOF) /* break if we reached END-OF-FILE */ break; if (ch == '\n') /* break if we reached a newline, because */ break; /* we have succesfully read a line */ } } 

清除缓冲区的另一个例子:

 char ch[1]; while(1){ ch[0] = fgetc(stdin); if(ch[0] == '\n' || ch[0] == EOF) break; }