scanf("%lf",&b);
fgets(str, 100, stdin);
在上述代码中fgets
直到我在%lf
(例如scanf("%lf ",&b);
)之后添加一个空格才被读取,或者按ctrl-d而不是在终端中输入。为什么会这样?
不要混合使用fgets()
和scanf()
。
scanf()
会留下一个换行符(当您按ENTER键时),它会终止fgets()
的输入读取,就像fgets()
一看到换行符就会终止一样,实际上您的fgets()
根本没有读取任何内容。
fgets()
:
fgets()从流中最多读取一个小于大小的字符并将它们存储到s所指向的缓冲区中。读取在EOF或换行符。如果读取了换行符,则会将其存储到缓冲器终止的空字节("\0")存储在最后一个缓冲区中的字符。
当格式字符串(scanf("%lf ",&b);
)中有空白时,scanf调用只会在输入非空白后返回,然后由fgets()
调用读取该非空白。这种方法容易出错。因为如果你不进一步阅读,你将被迫输入一些内容。
请参阅:为什么每个人都说不要使用scanf?我应该用什么代替?
scanf("%lf",...)
在输入中遇到空白时将停止并等待更多输入。在格式字符串中添加空格会导致从stdin
中删除空白字符,并返回函数。
导致scanf()
返回的另一种方法是让它识别某种形式的错误。一种方法就是让它看起来像是到达了文件的末尾。您还没有提到它,但您的主机系统有点像unix——键入CTRL-D(取决于终端设置,您可能需要在换行后键入CTRL-D,或者可能输入两次)会让它看起来像是遇到了文件结尾。如果您检查scanf()
的返回值,在这种情况下它也会返回EOF
。不同的系统需要不同的操作来触发文件结束。
无论哪种方式,在scanf()
返回之前都不能调用fgets(..., stdin)
。注意,触发文件结尾也可能(取决于终端设置)导致fgets(..., stdin)
返回EOF
(即,它不一定读取输入)。
在同一个流上混合使用scanf()
(或相关函数)和fgets()
(在本例中为stdin
)是一个非常糟糕的主意,因为它们确实以奇怪的方式交互(每个都依赖于与另一个没有提供的流交互的行为)