调用scanf() 之后的fgets() 函数可能1没有被跳过。 可能1在输入流中找到换行符后立即返回。
在fgets() 之前调用scanf() 几乎总是会导致scanf() 在输入流中留下一个未使用的换行符('\n'),这正是fgets() 正在寻找的。p>
为了混合使用scanf() 和fgets(),您需要从输入流中删除调用scanf() 留下的换行符。
刷新标准输入(包括换行符)的一种解决方案是类似于以下内容:
int c;
/* discard all characters up to and including newline */
while ((c = getchar()) != '\n' && c != EOF);
1 - 不看实际代码很难确定。
或者,正如Jerry Coffin 在他下面的评论中所建议的那样,您可以使用scanf("%*[^\n]");。 "%*[^\n]" 指令指示 scanf() 匹配不是换行符的内容并禁止分配转换结果。
/* match up to newline */
scanf("%*[^\n]");
/* discard the newline */
scanf("%*c");
来自http://c-faq.com/stdio/gets_flush1.html:
带有“%*[^\n]” 的初始scanf() 要么吃掉所有内容,但不包括换行符,或者失败。后续的“%*c”(或普通的旧getchar())将使用换行符,如果有的话。
最后一个“如果”也很重要:也许用户发出了 EOF 信号。在这种情况下,getchar() 或scanf("%*c") 可能——这个决定留给编写编译器的人——要么立即返回 EOF,要么返回给用户以获取更多输入。如果实施者选择后者,用户可能需要多点击一次“结束这件事”(^D、^Z、鼠标按钮、前面板开关或其他)。如果没有别的,这很烦人。
或者,正如Chris Dodd 在他下面的评论中所建议的那样,您可以使用scanf("%*[^\n]%*1[\n]");。 "%*[^\n]%*1[\n]" 指令指示 scanf() 匹配不是换行符的内容,然后匹配一个换行符并禁止分配转换结果。
/* match and discard all characters up to and including newline */
scanf("%*[^\n]%*1[\n]");