在C语言中,scanf和换行符的问题

4

我今天参加了C语言课程的一次测试,但我有理由认为答案可能是错误的。

scanf("%d\n", &x); // Evaluate the expression for the string "54321\n"

这个想法非常简单。找到一个整数并将扫描到的数字放置在与整数变量 x 对应的内存位置上。然而,我不认为这个对 scanf 的调用会终止。
就我所知,所有对标准 I/O 的 scanf 调用都会在按下回车键时终止,因此没有必要在格式字符串中包含换行符。实际上,这种冗余只会导致程序在寻找永远不会匹配的字符串时停滞不前。
有没有人能够澄清 scanf 函数的技术细节以解决这个问题?

2
在格式字符串中的尾随空格(无论是空格、制表符还是换行符)会导致交互式灾难。 - Jonathan Leffler
2个回答

5
我不相信scanf会终止。
例如,像"54321\n"这样的6个字符输入不足以使scanf("%d\n", &x)返回。程序停滞。一定还有其他事情发生。
'\n'指示scanf()消耗空格并一直执行,直到:
1. 检测到非空格字符。 2. stdin关闭 3. stdin上发生输入错误(很少)
由于stdin通常是行缓冲的,因此scanf()会以块的形式接收数据。
第一块123 Enter的数据不足以引起scanf("%d\n", &x)返回。必须发生上述3种情况之一。
任何随后带有某些非空格字符的输入都可以满足#1,例如:
4 5 6 Enter x y z Enter Enter Enter $ Enter ...
然后,scanf()将返回值为1,表示存储在x中的值123。上述4、x或$是检测到的非空格字符,导致完成。该字符将是后续在stdin上读取的下一个字符。
scanf("%d\n", &x) 几乎肯定是要使用错误代码,因为它强制要求用户输入另一行,并且不检查其返回值。

2
所有对标准I/O的scanf调用都会在按下回车键时终止,因此无需在格式字符串中包含换行符。这是正确的。格式字符串中的\n将忽略任意数量的空格,包括“ENTER”键;因此,您必须输入一个非空格字符来终止scanf()调用。所以,是的,\n是有问题的。
scanf()的手册页面上写道:
· 一个空白字符序列(空格、制表符、换行符等;请参见isspace(3))。该指令匹配输入中的任何数量的空格,包括零个。
顺便说一句,scanf()本身被认为是有问题的:为什么每个人都说不要使用scanf?我应该使用什么代替?

我认为提问者可能在暗示终端缓冲输入并在键入回车时将其发送到进程。 - Ed Heal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接