这如何清除输入缓冲区?

How does this clear the input buffer?

我找到了这段清除输入缓冲区的代码,但我不太明白它是如何工作的。 谁能简单解释一下?

do{
    fgets(string,LENGTH,stdin);
} while (strlen(string) > 0 && string[strlen(string) - 1] != '\n');

while (strlen(string) > 0 && string[strlen(string) - 1] != '\n');。因此,在字符串长度大于 0 时(即输入流中有字符等待时)执行 fgets 并且在字符串末尾不等于换行符时执行。如果输入的末尾等于换行符,则停止。我不确定为什么这段代码不继续并吃掉换行符,但它是安全的,因为所有标准阅读功能都会忽略初始换行符。 @barmar 有一个很好的建议(因为 fgets() 从输入缓冲区读取。如果缓冲区中有数据尚未读取, fgets() 不需要等待用户输入任何内容。)但是他们区别在于它们是否忽略尾随的换行符(当您按 ENTER 键时生成)。 fgets 保留尾随的换行符,但 gets 将其删除。

说它“清除输入缓冲区”是用词不当。它所做的是前进到下一行输入

该代码是一个 do/while 循环。它假定一个名为 string 的字符数组的大小至少为 LENGTH

循环的 body 尽可能多地读取一行,最多 LENGTH - 1 个字符:

fgets(string,LENGTH,stdin);

来自 fgets() 的 return 值被忽略 - 这是一个 bug,因为它可能意味着 string 没有分配给在失败的情况下(例如 EOF),我们可以永远循环。

循环的条件检查我们是否已经读到行尾。有一项测试表明字符串至少有一个字符(如果 fgets() 成功,它就会有),然后将最后一个字符与换行符进行比较:

while (strlen(string) > 0 && string[strlen(string) - 1] != '\n')

如果我们看到一个换行符,那么 fgets() 已经阅读了该行的其余部分;如果没有,它会从较长的输入行中读取 LENGTH-1 个字符,但仍有输入要消耗,所以继续循环。


固定版本:

while (fgets(string, LENGTH, stdin) && string[strlen(string) - 1] != '\n')
    ;

更简单的选择:

scanf("%*[^\n]%*c");

请注意,在这两种情况下,任何流错误都将保留,以便在下次尝试输入时检测到。