while循环中的scanf仅在第一次迭代时读取

时间:2015-04-25 09:04:02

标签: c scanf

注意:请注意,这不是Why is scanf() causing infinite loop in this code?的重复,我已经看过这个问题,但问题是他检查!=EOF而不是while ((read = scanf(" (%d,%d)\n", &src, &dst)) != EOF) { if(read != 2 || src >= N || src < 0 || dst >= N || dst < 0) { printf("invalid input, should be (N,N)"); } else matrix[src][dst] = 1; } 。此外,他的问题是不同的,&#34;无限循环&#34;仍然等待用户输入,它只是不退出。

我有以下while循环:

read

其意图是以格式(int,int)读取输入,在读取EOF时停止读取,并在收到无效输入时再次尝试。

问题是,scanf仅适用于第一次迭代,之后存在无限循环。程序不等待用户输入,只是假设最后一个输入是相同的。

srcdstint的类型为EOF

我已经查看了类似的问题,但是他们似乎无法检查scanf是否返回0而不是检查EOF,并且答案告诉他们切换到{{1}}。

2 个答案:

答案 0 :(得分:2)

您需要使用

int c;
while((c=getchar()) != '\n' && c != EOF);

while循环的末尾,以清除/刷新标准输入流(stdin)。为什么?答案如下:

您拥有格式字符串(scanf)的" (%d,%d)\n"要求用户输入

  1. 左括号((
  2. 一个数字(对于第一个%d
  3. 逗号(,
  4. 一个数字(最后%d
  5. 空格(scanf的格式字符串的第一个字符)和换行符(\n,即scanf的格式字符串的最后一个字符)被认为是是whitespace characters。让我们看看C11标准对格式字符串fscanf中的空白字符有什么看法(是的。我说fscanf因为当第一个参数是{{1}时,它等同于scanf }}):

      

    7.21.6.2 fscanf功能

         

    [...]

         
        
    1. 由空白字符组成的指令通过读取第一个非空白字符(仍然未读取)的输入来执行,或者直到不再能够读取字符为止。该指令永远不会失败
    2.   

    因此,所有空格字符都会跳过/丢弃所有空格字符(如果有),直到上面引用的第一个非空格字符为止。这意味着stdin格式字符串开头的空格会清除所有前导空格,直到第一个非空白字符和scanf字符相同为止。

    当您按照\n中的格式字符串输入正确的数据时,scanf的执行不会结束。这是因为scanf未在\n中找到非空白字符,并且仅在找到时才会停止扫描。所以,你必须删除它。

    下一个问题在于用户输入的内容不符合stdin的格式字符串。发生这种情况时,scanf会失败并返回。导致scanf失败的其余数据在scanf中占优势。 stdin在下次调用时会看到此字符。这也会导致scanf失败。这会导致无限循环。

    要解决此问题,您必须使用上面显示的方法在scanf循环的每次迭代中清除/清除/刷新stdin

答案 1 :(得分:-1)

scanf提示用户输入一些内容。假设用户按照他们的预期行事,他们会输入一些数字,然后按Enter键。

数字将存储在输入缓冲区中,但是换行符也是如此,这是因为它们点击了回车键。

scanf将解析数字以生成一个整数,它存储在src变量中。它在换行符处停止,该换行符保留在输入缓冲区中。

稍后,第二个scanf在输入缓冲区中查找换行符。它会立即找到一个,因此不需要提示用户输入任何内容。