无法弄清楚用C语言的scanf(“%[^ \ n] \ n”,input)会发生什么

问题描述 投票:2回答:2
char str[20];
scanf("%[^\n]\n", str);
printf(">>>>%s\n", str);

这是我的理解:第一部分“ [^ \ n]”表示接受除'\ n'以外的任何字符,以便从函数scanf中获取某些字符(例如空格)并将其存储在str中。第二个\ n用于匹配\ n,以使scanf结束,否则\ n将在输入流中释放,并留给下一个输入操作。

但是当我运行它时,结果使我感到困惑。

xhkjdeiMac:c xhkj$ ./hello
aaaaaaa
ccc
>>>>aaaaaaa

如您所见,我首先输入aaaaaaa并按Enter键,我认为它将aaaaaaa存储到str中并且已经与\ n匹配。但是我必须输入其他内容,例如ccc,然后我可以继续下一步并在控制台上打印str。

所以为什么会发生?为什么我必须输入其他内容并再次按Enter键以完成scanf?

c scanf
2个回答
0
投票

["%[^\n]\n"指定符序列意味着scanf将读取所有字符,直到找到\n,其次是期望为\n,直到发生它不能继续下一条语句。

例如,如果您使用scanf("\n"),则您需要为程序输入\n以继续下一条语句。

scanf规范状态:

(对于[set],如果集合的第一个字符是^,则所有不在集合中的字符都将匹配。

和:

所有转换说明符[,c和n除外在尝试解析输入之前,消耗并丢弃所有前导空白字符(好像通过调用isspace来确定)。这些消耗的字符不计入指定的最大字段宽度。

对于您发布为注释的代码(我认为是女巫,应移至问题本身)。

char str[20]; 
scanf("%[^\n]", str); 
printf(">>>>%s\n", str); 
scanf("%[^\n]", str); 
printf(">>>>%s\n", str); 
scanf("%[^\n]", str); 
printf(">>>>%s\n", str);

对于除n之外的每个转换说明符,最长的输入字符序列不超过任何指定的字段宽度,而该长度恰好是转换说明符所期望的,或者是它所期望的序列的前缀,是从流。 此消耗序列后的第一个字符(如果有的话)保持未读状态。如果使用的序列的长度为零,或者如果使用的序列无法按照指定的顺序进行转换,则匹配失败会发生,除非文件末尾,编码错误或读取错误阻止从流中输入,在这种情况下,它是输入失败。

长话短说,字符串消耗的是\n,不包括scanf,接下来的两个https://en.cppreference.com/w/cpp/io/c/fscanf的长度为零,事件的顺序符合预期。

来源:char str[20]; scanf("%[^\n]\n", str);


0
投票
"[^\n]"
© www.soinside.com 2019 - 2024. All rights reserved.