sscanf() 与 %s 匹配得太贪心了

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

我正在尝试解析格式为

1..4
的字符串,我不想将它们解析为字符串,它们可以是任何东西。

但是使用

sscanf

char *str = "1..4";
char a[128];
char b[128];
int c = sscanf(str, "%s..%s", a, b);
printf("a=%s, b=%s, c=%d\n", a, b, c);

给出以下输出:

a=1..4, b=��, c=1

只解析一个字符串?我做错了什么还是

sscanf
中的错误?

如果我删除这些点:

char *str = "1 4";
char a[128];
char b[128];
int c = sscanf(str, "%s %s", a, b);
printf("a=%s, b=%s, c=%d\n", a, b, c);

我得到:

a=1, b=4, c=2

这就是我在第一个示例中所期望的。

从文档中

.
未指定为格式字符。

更改格式字符串以解析为整数也可以:

char *str = "1..4";
int a;
int b;
int c = sscanf(str, "%d..%d", &a, &b);
printf("a=%d, b=%d, c=%d\n", a, b, c);

给予:

a=1, b=4, c=2
c scanf
3个回答
2
投票

%s
说明符在它看到的第一个非前导空格处停止读取。它在文档中说明here(向下滚动到“s”行):

任意数量的非空白字符,在找到的第一个空白字符处停止。终止空字符会自动添加到存储序列的末尾。


1
投票

%s
在第一个空格处终止,任何其他格式字符都将被忽略。

相反,我应该使用

%[^.]
它将读取所有字符,直到
.
:

char *str = "1..4";
char a[128];
char b[128];
int c = sscanf(str, "%[^.]..%s", a, b);
printf("a=%s, b=%s, c=%d\n", a, b, c);

这给出了预期的行为:

a=1, b=4, c=2

0
投票

%s
sscanf()
中使用时的使用说明是:

匹配一系列非空白字符; next 指针必须是指向字符数组的指针,该数组的长度足以容纳输入序列和自动添加的终止空字节 (' ')。输入字符串在空白处或最大字段宽度处停止,以先出现者为准。

如果不向

sscanf()
提供有关您尝试提取的字符串性质的更多具体信息,您尝试做的事情就不能简单地与
sscanf("%s")
一起使用。

我的建议是,既然您不希望第一个扫描的参数包含任何句点,那么使用

sscanf("%[]")
转换来指定不允许的内容:

匹配指定的接受字符集中的非空字符序列; next 指针必须是指向 char 的指针,并且必须有足够的空间容纳字符串中的所有字符以及终止空字节。通常跳过前导空白的现象被抑制。该字符串由特定集合中(或不包含)的字符组成;该集合由左括号 [ 字符和右括号 ] 字符之间的字符定义。如果开括号后的第一个字符是扬抑符 (^),则该集将排除这些字符。要在集合中包含右括号,请将其作为左括号或扬抑符之后的第一个字符;任何其他位置都将结束该组。连字符 - 也很特殊;当放置在其他两个字符之间时,它将所有中间字符添加到集合中。要包含连字符,请将其作为最后一个右括号之前的最后一个字符。例如,[^]0-9-] 表示集合“除右括号、零到九和连字符之外的所有内容”。字符串以不在(或带扬抑符的)集合中的字符出现或当字段宽度用完时结束。

如果您知道愿意接受任何不包含句点的字符串,请尝试以下不包含句点的字符串:

char *str = "1..4";
char a[128];
char b[128];
int c = sscanf(str, "%[^.]..%s", a, b);
printf("a=%s, b=%s, c=%d\n", a, b, c);
© www.soinside.com 2019 - 2024. All rights reserved.