scanf中的%[^\n]s不等待输入并被跳过了。

6
在下面的代码循环中,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)。 - Shiping
2个回答

3
首先,结尾的s不是%[格式说明符的一部分,因此请删除它并让我们谈论%[^\n]
现在,%[^\n]告诉scanf扫描直到出现换行符('\n')或EOF为止,并将其存储在相应的参数中,这里是arr
这里有一个问题:%[^\n]如果要读取的第一个字符是\n就失败了
"等等",你说。 "我没有输入一个孤独的回车。那么,为什么会失败?" 你确实没有。但请记住,你按下的Enter键是为了前一行?结果,前一次调用scanf获取直到\n的所有内容,留下\n 并返回。所以,在循环的下一次迭代中,scanf看到了前一次调用scanf留下的\n字符,失败并返回0。
至于空格,它是一个空白字符。在scanf中,空白字符指示它扫描并丢弃所有空白字符,直到第一个非空白字符。因此,它删除了\n(因为它是一个空格字符),并且scanf将等待进一步的输入。

1
使用格式%[^\n]scanf()在读取换行符后停止。因此,在第一个输入后,会留下一个未被消耗的换行符。 因此,随后的scanf()调用根本不读取任何输入。
%[^\n]中有一个空格时,scanf()会忽略任意数量的空格字符。因此,scanf()会忽略剩余的换行符。来自scanf

一系列空格字符(空格、制表符、换行符等;见isspace(3))。该指令匹配任意数量的空格,包括输入中没有空格的情况。

顺便说一句,在格式字符串末尾不需要那个额外的s
使用 fgets() 函数通常比 scanf() 更好(如果有空间,fgets() 会将换行符读入缓冲区)。另请参阅:为什么大家都说不要使用 scanf?应该使用什么代替?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接