如何打印所有阵列?现在,阵列将打印到最后一部分,所以如果我输入:
hel'lo hi
将输出
hel
lo
但不是hi
。
这是代码:
char in[1000];
printf("read these lines: ");
while(scanf("%29[a-zA-Z]%*[^a-zA-Z]",in)==1){
printf("%s\n",in);
}
答案 0 :(得分:0)
使用scanf
正确解析字符串可能非常棘手,这就是为什么(根据我的个人经验)很少使用它。
为什么你的代码显然失败的原因可能会变得清晰,如果不是以交互方式运行程序,我们会将数据传输到其中。
$ printf "%s" "hel'lo hi" | ./scanf
read these lines: hel
lo
hi
将hel
和read these lines:
放在同一条线上放一点烦恼,程序按照您的意图运作。
原因是,scanf
尝试消耗尽可能多的字符,直到遇到一个字符,该字符不再与格式字符串匹配或者到达输入流的末尾。
我们将两个指令%29[a-zA-Z]
标记为 A 和%*[^a-zA-Z]
以及 B 。
如果您将数据传输到您的程序中,以下数据将显示在stdin
'h' 'e' 'l' '\'' 'l' 'o' ' ' 'h' 'i' <EOF>
----------- ---- ------- --- ------- -----
A B A B A EOF
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~ ~~~~~~~~~~~~~
1st call 2nd call 3rd call
在第一个循环期间,scanf
消耗'h' 'e' 'l' '\''
,因为此时后面的字符l
与格式字符串不匹配。然后,我们有第二次运行,直到'h'
,最后一次运行,结束过早(不使用 B )。
如果您以交互方式运行程序,我们会遇到以下情况:
'h' 'e' 'l' '\'' 'l' 'o' ' ' 'h' 'i' '\n' <scanf blocks>
----------- ---- ------- --- ------- -----? // Maybe B can continue
A B A B A B
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~ ~~~~~~~~~~~~~
1st call 2nd call 3rd call
scanf
只返回两次然后阻止,因为可能会有更多数据出现,可以匹配 B 。
我们可以尝试以格式字符串切换指令,以便首先使用不需要的数据%*[^a-zA-Z]%29[a-zA-Z]
,这样我们也可以解析像";hel;lo"
这样的输入,但是因为{{ 1}}指令匹配非空字符序列,原始示例%[
不再有效。
为了正确解决这个问题,在处理每个角落的情况下,我们必须采用不同的方法并使用两个不同的"hel'lo hi"
调用,一个消耗不需要的数据,另一个消耗真实数据。我也增加了调用scanf
的精度,因为这是缓冲区的大小。为什么要保留1000个字节并仅使用29?
1000