我正在尝试使用 sscanf
解析 xxxxxx(xxxxx)
格式字符串,如下所示:
sscanf(command, "%s(%s)", part1, part2)
但是 sscanf
似乎不支持这种格式,因此 part1
实际上包含了整个字符串。
谁有这方面的经验请分享...
谢谢
最佳答案
将代码转换为程序:
#include <stdio.h>
int main(void)
{
char part1[32];
char part2[32];
char command[32] = "xxxxx(yyyy)";
int n;
if ((n = sscanf(command, "%s(%s)", part1, part2)) != 2)
printf("Problem! n = %d\n", n);
else
printf("Part1 = <<%s>>; Part2 = <<%s>>\n", part1, part2);
return 0;
}
运行时,它会产生'问题! n = 1
'。
这是因为第一个 %s
转换说明符跳过前导空白,然后扫描“非空白”字符直到下一个空白字符(或者,在这种情况下,结束字符串)。
您需要使用(否定的)字符类或扫描集来获得您想要的结果:
#include <stdio.h>
int main(void)
{
char part1[32];
char part2[32];
char command[32] = "xxxxx(yyyy)";
int n;
if ((n = sscanf(command, "%31[^(](%31[^)])", part1, part2)) != 2)
printf("Problem! n = %d\n", n);
else
printf("Part1 = <<%s>>; Part2 = <<%s>>\n", part1, part2);
return 0;
}
这会产生:
Part1 = <<xxxxx>>; Part2 = <<yyyy>>
注意格式中的 31;它们可以防止溢出。
I'm wondering how does %31 works. Does it work as
%s
and prevent overflow or does it just prevent overflow?
对于给定的数据,这两行是等价的并且都足够安全:
if ((n = sscanf(command, "%31[^(](%31[^)])", part1, part2)) != 2)
if ((n = sscanf(command, "%[^(](%[^)])", part1, part2)) != 2)
%[...]
符号是一种转换规范; %31[...]
也是如此。
C 标准说:
Each conversion specification is introduced by the character %. After the %, the following appear in sequence:
- An optional assignment-suppressing character *.
- An optional decimal integer greater than zero that specifies the maximum field width (in characters).
- An optional length modifier that specifies the size of the receiving object.
- A conversion specifier character that specifies the type of conversion to be applied.
31 是(可选)最大字段宽度的示例。 [...]
部分是一个 scanset,它可能被视为 s
转换说明符的特例。 %s
转换说明符大约等同于 %[^\t\n]
。
31比字符串长度少1;最后的空值不计入该长度。由于 part1
和 part2
都是 32 个 char
的数组,因此 %31[^(]
或 %31[^)]
转换说明符防止缓冲区溢出。如果第一个字符串在 (
之前超过 31 个字符,您将得到返回值 1,因为文字左括号不匹配。同样,第二个字符串将被限制为31 个字符,但您很难判断 )
是否在正确的位置。
关于c - c中的sscanf函数用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12399186/