c-为什么我们在从scanf读取数据时必须按下ctrl-d


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)是一个非常糟糕的主意,因为它们确实以奇怪的方式交互(每个都依赖于与另一个没有提供的流交互的行为)

相关内容

  • 没有找到相关文章

最新更新