请参阅此SO问题Why is the gets function so dangerous that it should not be used? fgets()不起作用的原因可能是您没有处理scanf在前面的语句中留下的换行符。 您可以修改scanf格式字符串以将其考虑在内:scanf("%d *[^\n]", &N); *[^\n]表示忽略整数输入之后的所有非换行符的内容,但不要对换行符做任何操作(跳过它)。 当您使用scanf("%d",&num)时,会遇到13和enter,13存储在num中,并且newline字符仍在输入缓冲区中。当您从stdin读取fgets时,它会将\n视为您已输入的数据,并跳过fgets()语句 您不能刷新输入缓冲区,但可以执行此操作fseek(stdin,0,SEEK_END);在每个fgets语句之前添加此内容
7条答案
按热度按时间wqlqzqxt1#
在调用gets()或fgets()之前调用getchar()。由于gets()或fgets()被跳过是因为stdin中先前的输入中已经存在“\n”,调用getchar()将导致其本身被跳过,而不是gets()或fgets()或任何其他类似的函数。但请记住,这更多的是一种黑客行为,而不是一种标准的解决方案(我认为是这样),并且禁止使用gets()。
jbose2ul2#
因为
gets()
使用起来非常危险,所以一些C库已经完全删除了它,并用一个什么都不做的版本来代替它。请改用fgets()。
oewdyzsn3#
使用flush(标准输入);在gets()之前
xpszyzbs4#
使用
gets()
会遇到很多问题而不是选择
fgets()
请参阅此SO问题Why is the gets function so dangerous that it should not be used?
fgets()
不起作用的原因可能是您没有处理scanf在前面的语句中留下的换行符。您可以修改scanf格式字符串以将其考虑在内:
scanf("%d *[^\n]", &N);
*[^\n]
表示忽略整数输入之后的所有非换行符的内容,但不要对换行符做任何操作(跳过它)。当您使用
scanf("%d",&num)
时,会遇到13和enter
,13
存储在num
中,并且newline
字符仍在输入缓冲区中。当您从stdin
读取fgets
时,它会将\n
视为您已输入的数据,并跳过fgets()
语句您不能刷新输入缓冲区,但可以执行此操作
fseek(stdin,0,SEEK_END);
在每个fgets语句之前添加此内容q35jwt9p5#
看一看
gets()
reference从标准输入获取字符串
从标准输入(stdin)读取字符,并将其作为C字符串存储到str中,直到到达换行符或文件结尾。
如果找到换行符,则不将其复制到字符串中。
在复制到字符串的字符之后自动追加终止空字符。
请注意,gets与fgets有很大的不同:gets不仅使用stdin作为源代码,而且在结果字符串中不包含结束换行符,也不允许指定str的最大大小(这可能导致缓冲区溢出)。
因此,基本上
gets()
不仅不安全(可能导致缓冲区溢出),而且还读取输入缓冲区中的内容。我建议您使用
fgets()
,但是如果您想要一个快速(* 和懒惰和愚蠢 *)的解决方案,只需刷新输入缓冲区:btxsgosb6#
将下面的函数添加到您的代码中,并享受它。
这个功能可以影响所有空格和退格键!!!
elcex8rz7#
您可能需要丢弃该行的其余部分,并移到下一行的开头。您可以执行以下操作:
这将丢弃当前行的其余部分(可能已使用
scanf()
等部分读取),并移到下一行。尽管
fflush(stdin)
也可能丢弃输入,但这是非标准行为,不鼓励这样做。永远不要使用
gets(myString)
,因为它不安全,已经从C标准中完全删除了。它不强制字符串的尺子,因此您可以越过缓冲区的末尾并覆盖RAM中的其他值,从而导致缓冲区溢出,这可能是一个安全漏洞。使用fgets(myString, myStringSize, stdin)
;若要去掉结果字符串中的换行符,请使用myString[strcspn(myString, "\n")] = 0;
。