【问题标题】:scanf format string not recognized [closed]无法识别scanf格式字符串[关闭]
【发布时间】:2018-05-14 17:55:05
【问题描述】:

我已为以下程序插入以下输入:

a b c d e

在 e 字母之后我按下了 Enter,但程序在 scanf 上阻塞,因为 i 等于 3。 似乎 scanf 无法从标准输入中获取其他字符。 提前感谢您的帮助。

    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        char a[5];
        for (int i = 0; i < 5; i++)
        {
            scanf("%c ", a + i);
            printf("i = %d a[%d] = %c \n", i, i, a[i]);
        }

        int i = 0;
        while( i < 5 )
        {
            printf("%c ", a[i]);
            i++;
        }

        return 0;
    }

【问题讨论】:

    标签: c input buffer scanf stdin


    【解决方案1】:

    当 i == 3 时它不会阻塞——它完成了迭代——它在 i == 4 时阻塞。

    这是因为 scanf 格式中 %c 之后的空格 - 空格会导致 scanf 读取输入并向上跳过空格,直到找到非空格字符。然后,该非空白字符将作为下一个要读取的字符留在 FILE 输入缓冲区中。因此,在循环的第 5 次迭代中(i == 4),它读取 e 然后读取空白以寻找非空白。因此,换行符被跳过(它是空格)并开始(尝试)读取阻塞的下一行。

    一旦你提供了下一行(假设它不是空的/全是空格),它将得到一个非空格字符,scanf 将返回。

    【讨论】:

      【解决方案2】:

      使用 scanf 从标准输入一次获取一个字符不是一个好主意。如果用户键入了多个字符,您可能会溢出缓冲区,因为空字符没有空间。这也会在标准输入中留下多余的字符。

      另一个想法是使用特殊格式字符串标志一次获取 5 个字符,然后打印它们或对它们做任何你想做的事情。

      您可以使用标志"%5c",其中 5 是任意整数,表示精确扫描 5 个字符

      这是修改后的代码

      #include <stdio.h>
      #include <stdlib.h>
      
      int main()
      {
          char a[5];
          scanf("%5c", a);
      
          int i = 0;
          while( i < 5 )
          {
              printf("%c ", a[i]);
              i++;
          }
      
          return 0;
      }
      

      现在没有阻塞了。

      【讨论】:

      • 这是错误的并且溢出了缓冲区,因为你需要空间用于字符串的 nul 终止
      • 我的意思是它会在标准输入中留下未使用的字符,我会编辑。
      • 这行不通。 scanf 中的%s 将在第一个空白处终止。因此,只有字符 a 会被读入数组。
      • 将其更改为 %5c,它适用于空白字符。
      • @JoshWeinstein 我认为这也行不通,因为空格也会被读入数组。因此,如果用户输入a b c d e,那么数组 a 中的 5 个插槽最终将包含这 5 个字符:a b c
      猜你喜欢
      • 2020-05-24
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2021-07-22
      相关资源
      最近更新 更多