试图用两个不同的分隔符解析一个字符串。一个空格,后跟2个逗号,后跟空格/换行符。
scanf("%s%[^,]s%[^,]s%s", v1, v2, v3, v4);
由于某种原因,写入stdin的字符串分隔为“abc asc,abc abc”将为v1和v2生成正确的结果。但v3和v4的垃圾结果。
可能是什么原因?
编辑:这是完整的代码
char v1[MAX_LENG], v2[MAX_LENG], v4[MAX_LENG], v3[MAX_LENG];
scanf("%s%[^,]%[^,]%s", v1, v2, v3, v4);
printf("%s%s%s%s", v1, v2, v3, v4);
它打印读取A
使用以下:
"%s %[^,], %s %s"
输出:
$ gcc -Wall main.c
$ ./a.out
abc def, hij klm <<<<< Input
abc
def
hij
klm
scanf()
电话:
scanf("%s%[^,]s%[^,]s%s", v1, v2, v3, v4);
将第一个字符串读取到空白区域(空白,制表符等)到v1
;然后它读取第二个字符串(包括前导空格)到逗号到v2
。它然后失败,因为下一个字符是逗号,但代码正在扫描s
。扫描集符号是%[…]
或%[^…]
;它不是s
转换的修饰符;这是完全独立的,在]
完成。所以,前两个字段被读取;然后转换失败。所以,scanf()
返回2 - 但你没有注意到这一点。您必须始终检查scanf()
(或任何输入函数)的返回,以确保获得预期的结果。
请注意,只是在扫描设置后删除s
不是一个完整的解决方案。下一个字符是逗号,因此第二个%[^,]
扫描集将失败;你必须提供一些东西来阅读逗号。你重复“扫描设置后的s
”错误,但是如果这也是固定的,那么你就会陷入战斗机会。
但是,您的输入声称是:
abc asc, abc abc
那里只有一个逗号。因此,要解析它,您将使用:
if (scanf("%s %[^,] , %s %s", v1, v2, v3, v4) != 4)
…something went wrong…
扫描集之前的空白会跳过任何前导空格(三次转换%c
,%n
和%[…]
不会跳过前导空格;其他所有空格都会跳过。所有其他空白都可以在不改变行为的情况下被省略(并且在逗号文字之前省略空白是arguably一个好主意,正如chux所说 - 但正如我所说,空白之前它也没有直接伤害,至少只要那些阅读代码的人有足够的经验知道这意味着什么)。
当涉及到错误报告时,如果你读完整行(fgets()
或者POSIX getline()
)然后用scanf()
解析它会更容易。通过这种方式,它可以更轻松地报告错误。