我正在尝试解析格式为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
答案 0 :(得分:2)
%s
说明符停止在它看到的第一个非前导空格处读取。它在文档here中说明(向下滚动到" s"行):
任意数量的非空白字符,在找到的第一个空白字符处停止。在存储序列的末尾会自动添加一个终止空字符。
所以没有。与初学者相反,scanf
或任何其他标准库函数都被破坏了。信仰。 (不是说OP是初学者 - 它只是初学者的共同态度)
答案 1 :(得分: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
答案 2 :(得分:0)
%s
中sscanf()
使用的手册是:
匹配一系列非空白字符;下一个指针必须是一个指向字符数组的指针,该指针足够长以容纳输入序列和终止空字节(' \ 0'),这是自动添加的。输入字符串在空格或最大字段宽度处停止,以先到者为准。
如果没有向sscanf()
提供有关您尝试提取的字符串性质的更多具体信息,那么您尝试做的事情不能简单地与sscanf("%s")
一起使用。
我的建议是,因为您不希望首次扫描的参数包含任何句点,然后使用sscanf("%[]")
转换来指定不允许的内容:
匹配指定的接受字符集中的非空字符序列;下一个指针必须是指向char的指针,并且字符串中的所有字符必须有足够的空间,加上一个终止空字节。通常跳过前导空格被抑制。该字符串由特定集合中的字符组成(或不在其中);该集合由open括号[character和close bracket]字符之间的字符定义。如果开括号后的第一个字符是旋音(^),则该组将排除这些字符。要在组中包含一个小括号,请将其作为开括号或旋转后的第一个字符;任何其他位置将结束该集。连字符 - 也很特别;当放置在两个其他字符之间时,它会将所有插入的字符添加到集合中。要包含连字符,请将其设置为最后一个关闭括号之前的最后一个字符。例如,[^] 0-9-]表示除了小括号,0到9和连字符"之外的所有内容。字符串的结尾是字符的外观,不在(或者,有一个旋转,in)设置或字段宽度用完时。
如果您知道您愿意接受任何不包含句号的字符串,请尝试以下排除句点的内容:
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);