使用带有2个不同分隔符的scanf解析字符串

问题描述 投票:0回答:2

试图用两个不同的分隔符解析一个字符串。一个空格,后跟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

c
2个回答
0
投票

使用以下:

"%s %[^,], %s %s"

输出:

$ gcc -Wall main.c
$ ./a.out
abc def, hij klm   <<<<< Input
abc
def
hij
klm

0
投票

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()解析它会更容易。通过这种方式,它可以更轻松地报告错误。

© www.soinside.com 2019 - 2024. All rights reserved.