sscanf返回1读取字符串
当它返回一个时意味着什么 谁能帮我找出我的问题所在sscanf返回1读取字符串,c,C,当它返回一个时意味着什么 谁能帮我找出我的问题所在 char* line = "\"ThisId\":\"\""; char key[32], value[512]; if (sscanf(line, "\"%31[^\"]\":\"%511[^\"]\"", key, value) != 2) { return false; } 我想读取key=ThisId 及 在这种情况下,值应为空 看起来key得到了整个字符串,因此value不会得到任何值 原因是格式说明符[…]与空输入不匹配。
char* line = "\"ThisId\":\"\"";
char key[32], value[512];
if (sscanf(line, "\"%31[^\"]\":\"%511[^\"]\"", key, value) != 2) {
return false;
}
我想读取key=ThisId
及
在这种情况下,值应为空
看起来key得到了整个字符串,因此value不会得到任何值 原因是格式说明符
[…]
与空输入不匹配。例如,赋予链接C标准草案中的含义,并注明“非空”(重点是我的):
[…匹配一组预期字符(扫描集)中的非空字符序列
因此,“空”值,即两个\“
之间没有任何字符的输入,将与格式不匹配,这就是为什么在这种情况下scanf
的结果不是2
不管怎样,
scanf
有几种输入格式,中间有几个字符,这通常会变得非常棘手,而且容易出错。我建议你读完整的一行,例如使用fgets
,然后解析它,例如使用strtok
,或者strchr
。因为你手头已经有一行,你当然会跳过f获取
-thing.原因是格式说明符[…]与空输入不匹配。例如,请授予链接的C标准草案中的的的含义,并注意“非空”(重点是我的):
[…匹配一组预期字符(扫描集)中的非空字符序列
因此,“空”值,即两个\“
之间没有任何字符的输入,将与格式不匹配,这就是为什么在这种情况下scanf
的结果不是2
不管怎样,scanf
有几种输入格式,中间有几个字符,这通常会变得非常棘手,而且容易出错。我建议你读完整的一行,例如使用fgets
,然后解析它,例如使用strtok
,或者strchr
。因为你手头已经有一行,你当然会跳过f获取
-对象。这是因为[^\“]
将读取字符,直到到达\”
。因为您的输入“\“ThisId\”:\“\”;
不包含第二个字符串的任何额外字符。
sscanf
没有读取值的任何内容
如果您打算读取空值,请按如下所示在输入中输入'
char* line = "\"ThisId\":\" \"";
这是因为[^\“]
将读取字符,直到到达\”
。因为您的输入“\“ThisId\”:\“\”;
不包含第二个字符串的任何额外字符。
sscanf
没有读取值的任何内容
如果您打算读取空值,请按如下所示在输入中输入'
char* line = "\"ThisId\":\" \"";
我的问题在哪里
char* line = "\"ThisId\":\"\"";
char key[32], value[512];
if (sscanf(line, "\"%31[^\"]\":\"%511[^\"]\"", key, value) != 2) {
return false;
}
当说明符无法匹配任何内容时,sscanf()
的预期不正确
由于行
没有匹配的%511[^\“]”
,因此扫描停止。值[]
不变,scanf()
报告在这种情况下成功扫描的1
说明符的数量
还有一个问题
使用下面的line2
,sscanf()
将值[]
填充为“xyz”
,sscanf()
按预期返回2
char* line2 = "\"ThisId\":\"xyz\"";
使用下面的line3
,sscanf()
将值[]
填充为“xyz”
和sscanf()
返回2,即使line3
没有最终的“\”
使用下面的line4
,sscanf()
将值[]
填充为“xyz”
,sscanf()
返回2,即使line4
在最后的“\”
之后会有额外的垃圾
OP的目标是匹配两种不同的sscanf
格式中的任何一种。我发现使用字符串文字连接使代码更容易理解和维护
#define KEY_FMT "\"%31[^\"]\"
#define SEP_FMT ":"
#define VAL_FMT "\"%511[^\"]\"
#define EMPTY_FMT "\"\"
KEY_FMT SEP_FMT VAL_FMT /* key and value */
KEY_FMT SEP_FMT EMPTY_FMT /* key and empty value */
一个简单的解决方案是扫描字符串两次,然后测试扫描是否结束。代码可以使用最后一个%n”
来测试这一点,以记录到目前为止扫描到的字符数(如果扫描到该点)
一个有用的变化是分部分扫描
int n = 0;
sscanf(line, KEY_FMT SEP_FMT N_FMT, key, &n);
if (n == 0) {
return false; // Key or separator not found
}
line += n; // advance
n = 0;
sscanf(line, VALUE_FMT N_FMT, &n);
if (n > 0 && line[n] == '\0') {
return true; // Found value
}
n = 0;
sscanf(line, EMPTY_FMT N_FMT, value, &n);
if (n > 0 && line[n] == '\0') {
value[0] = '\0';
return true; // Found empty value
}
return false;
最后,考虑在扫描的各个部分中允许空白。< /P>
#define KEY_FMT " \"%31[^\"]\"
#define SEP_FMT " :"
#define VAL_FMT " \"%511[^\"]\"
#define EMPTY_FMT " \"\"
#define N_FMT " %n"
我的问题在哪里
char* line = "\"ThisId\":\"\"";
char key[32], value[512];
if (sscanf(line, "\"%31[^\"]\":\"%511[^\"]\"", key, value) != 2) {
return false;
}
当说明符无法匹配任何内容时,sscanf()
的预期不正确
由于行
没有匹配的%511[^\“]”
,因此扫描停止。值[]
不变,scanf()
报告在这种情况下成功扫描的1
说明符的数量
还有一个问题
使用下面的line2
,sscanf()
将值[]
填充为“xyz”
,sscanf()
按预期返回2
char* line2 = "\"ThisId\":\"xyz\"";
使用下面的line3
,sscanf()
将值[]
填充为“xyz”
和sscanf()
返回2,即使line3
没有最终的“\”
使用下面的line4
,sscanf()
将值[]
填充为“xyz”
,sscanf()
返回2,即使line4
在最后的“\”
之后会有额外的垃圾
OP的目标是匹配两种不同的sscanf
格式中的任何一种。我发现使用字符串文字连接使代码更容易理解和维护
#define KEY_FMT "\"%31[^\"]\"
#define SEP_FMT ":"
#define VAL_FMT "\"%511[^\"]\"
#define EMPTY_FMT "\"\"
KEY_FMT SEP_FMT VAL_FMT /* key and value */
KEY_FMT SEP_FMT EMPTY_FMT /* key and empty value */
一个简单的解决方案是扫描字符串两次,然后测试扫描是否结束。代码可以使用最后一个%n”
来测试这一点,以记录到目前为止扫描到的字符数(如果扫描到该点)
一个有用的变化是分部分扫描
int n = 0;
sscanf(line, KEY_FMT SEP_FMT N_FMT, key, &n);
if (n == 0) {
return false; // Key or separator not found
}
line += n; // advance
n = 0;
sscanf(line, VALUE_FMT N_FMT, &n);
if (n > 0 && line[n] == '\0') {
return true; // Found value
}
n = 0;
sscanf(line, EMPTY_FMT N_FMT, value, &n);
if (n > 0 && line[n] == '\0') {
value[0] = '\0';
return true; // Found empty value
}
return false;