【问题标题】:%[^\n]s in scanf does not wait for input and gets skippedscanf 中的 %[^\n]s 不等待输入并被跳过
【发布时间】:2017-03-26 13:13:02
【问题描述】:

在下面代码的循环中,scanf("%[^\n]s",array) 不起作用。它不等待输入并被跳过。但是% 之前的空格可以解决问题。为什么?

这是错误的程序:

#include <string.h>
#include <stdio.h>

int main()    
{    
    int t;
    scanf("%d",&t);
    while(t--){
        char arr[199];
        scanf("%[^\n]s",arr);
        printf("%s",arr);
    }
    return 0;
}

这是正确的代码:

#include <string.h>
#include <stdio.h>

int main()
{    
    int t;
    scanf("%d",&t);
    while(t--){
        char arr[199];
        scanf(" %[^\n]s",arr);
        printf("%s",arr);
    }
    return 0;
}

为什么% 之前需要一个空格才能按预期工作?

【问题讨论】:

  • 这是因为您有一个需要跳过的换行符。第一个 scanf 只是读取数字,您仍然在输入中留下换行符。如果没有空间来吸收剩余的换行符,循环中的 scanfs 也不会读取换行符。实际上你可以在循环中使用 scanf("%s", arr) 。

标签: c string input scanf


【解决方案1】:

首先,结尾的s 不是%[ 格式说明符的 部分,所以删除它并讨论%[^\n]

现在,%[^\n] 告诉 scanf 做的是扫描所有内容,直到出现换行符 ('\n') 或 EOF,以先到者为准,并将其存储在相应的参数中,在本例中为 @987654328 @。

这里有一个问题:如果要读取的第一个字符是\n%[^\n] 会失败

'等等',你说。 '我没有单独输入。那么,为什么它失败了?'。真的。你没有。但是还记得您为上一行按下的 Enter 吗?结果是,之前对scanf 的调用会抓取所有内容,直到\n\n 留在那里并返回。因此,在循环的下一次迭代中,scanf 看到上一次调用 scanf 留下的这个 \n 字符,失败并返回 0。

至于空格,它是一个空白字符。 scanf 中的空白字符指示它扫描并丢弃所有空白字符,直到第一个非空白字符。因此,它会删除 \n(因为它是一个空白字符)并且 scanf 将等待进一步的输入。

【讨论】:

    【解决方案2】:

    使用这种格式%[^\n]scanf() 在读取换行符后停止。所以,在第一次输入之后,剩下一个没有被消耗的换行符。 因此,后续的 scanf() 调用根本不会读取任何输入。

    %[^\n] 中有空格,scanf() 会忽略任意数量的空白字符。因此,scanf() 会忽略剩余的换行符。来自scanf

    一系列空白字符(空格、制表符、换行符等;参见 空间(3))。该指令匹配任意数量的空白, 在输入中不包括任何内容。

    顺便说一句,您不需要在格式字符串末尾添加额外的s

    使用fgets(),它通常优于scanf()(如果有空间,fgets() 会将换行符读入缓冲区)。另请参阅:Why does everyone say not to use scanf? What should I use instead?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多