scanf 和来自先前输入的输入流中的左侧字符 → setvbuf?

scanf and a left character in the input stream from previous input → setvbuf?

我有一道理解题。好久没用过C了,今天翻了一下C语言的线程,偶然发现了下面这句话,我粗略地引用在这里: “scanf 正在读取您输入的上一个输入中留在输入流中的字符。” 有件事进入了我的记忆。在那些日子里,我使用 setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdin, NULL, _IONBF, BUFSIZ); 来避免这种行为。这些行确保输入流中没有上一个输入留下的字符。

我现在的问题是:这是一个好的解决方案吗?这是我一直想知道的

我想你的意思是你会在 调用 scanf 之后调用 setvbuf ,并且至少在在一个 C 实现中,它具有丢弃标准输入缓冲区中 scanf 未使用的任何“剩余”字符的效果。

这不是丢弃“剩余”字符的好方法,因为 C 标准规定 setvbuf“只能在流与打开的文件相关联之后且在任何其他操作之前使用(除了对 setvbuf 的不成功调用)在流上执行”。 (N1570 §7.21.5.6p2。)违反此规则 应该 只会导致 setvbuf 失败,但这意味着它不会执行您想要的操作。

做你想做的最好的方法是不使用scanf。相反,为您的输入编写一个真正的解析器,并逐个字符(使用 getchar)或逐行(使用 getlinefgets)输入它。一个真正的解析器有原则地处理白色 space(包括换行符)和语法错误,因此永远不会发现自己有“遗留”输入。

不幸的是,编写真正的解析器是一本书长度的主题,所以我只会说 sscanf 在真正的解析器中也永远没有用。 ( 有用的标准库函数包括 strsepstrchrstrto* 系列。)

在极少数情况下(通常涉及处理 interactive 输入),您确实必须丢弃行尾的垃圾。在那些情况下,方法是使用这个循环:

int c;
do c = getchar();
while (c != '\n' && c != EOF);