使用sscanf解析十进制字符串

使用sscanf解析十进制字符串,c,linux,glibc,scanf,C,Linux,Glibc,Scanf,我想将字符串解析为整数。 字符串可以包含任何数据,包括无效整数或浮点整数。这是我的代码,显示了我如何使用sscanf(): 其中字符串作为参数传递 我预计此代码在“3.5”数据上会失败。但不幸的是,sscanf()将“3.5”截断为3,并将其写入temp整数。 怎么了 我是否正确使用了sscanf()?以及如何通过使用sscanf实现此任务,而无需编写手写解析器(通过直接调用strtoul()或类似方法)。3是一个有效的整数。不幸的是,sscanf不够复杂,无法向前看,无法检测到3.5是一个浮点

我想将字符串解析为整数。 字符串可以包含任何数据,包括无效整数或浮点整数。这是我的代码,显示了我如何使用
sscanf()

其中字符串作为参数传递

我预计此代码在
“3.5”
数据上会失败。但不幸的是,
sscanf()
“3.5”
截断为
3
,并将其写入
temp
整数。 怎么了


我是否正确使用了
sscanf()
?以及如何通过使用
sscanf
实现此任务,而无需编写手写解析器(通过直接调用
strtoul()
或类似方法)。

3
是一个有效的整数。不幸的是,
sscanf
不够复杂,无法向前看,无法检测到
3.5
是一个
浮点值
,无法给出任何结果


尝试使用strtol测试返回指针,看看它是否解析了整个字符串。

3
是一个有效的整数。不幸的是,
sscanf
不够复杂,无法向前看,无法检测到
3.5
是一个
浮点值
,无法给出任何结果


尝试使用strtol测试返回指针,看看它是否解析了整个字符串。

sscanf
只解析它可以解析的字符串部分。您可以向其添加另一种格式,如
“%d%s”
。如果
%s
说明符捕获了一个非空字符串(例如
.5
),则抛出一个错误。

sscanf
仅解析它可以解析的字符串部分。您可以向其添加另一种格式,如
“%d%s”
。如果
%s
说明符捕获非空字符串(如
.5
),则抛出错误。

使用
%n
记录扫描在缓冲区中的位置。
我们可以使用它来确定是什么停止了扫描

int n;
int res = sscanf(string, "%"SCNu32 " %n", &temp, &n);
if (0 != errno || 1 != res || string[n] != '\0')
  return HEX_ECONVERSION;
追加
“%n”
表示忽略以下空白,然后注意缓冲区位置。如果没有其他垃圾,如
“.5”
,则
字符串[n]
将指向空终止符


确保设置了
temp
后,确保测试
n
。这是在上面使用
1!=res

“%n”
不影响使用
“%n”
记录扫描在缓冲区中的位置时所返回的值。
我们可以使用它来确定是什么停止了扫描

int n;
int res = sscanf(string, "%"SCNu32 " %n", &temp, &n);
if (0 != errno || 1 != res || string[n] != '\0')
  return HEX_ECONVERSION;
追加
“%n”
表示忽略以下空白,然后注意缓冲区位置。如果没有其他垃圾,如
“.5”
,则
字符串[n]
将指向空终止符


确保设置了
temp
后,确保测试
n
。这是在上面使用
1!=res


“%n”
不影响
sscanf()

返回的值,这是否意味着
sscanf()
甚至不表示
错误?只有通过使用一些技巧,如“%d%s”?在有效字符串后添加字符不是错误。这是否意味着
sscanf()
甚至不表示
错误?只有通过使用一些技巧,如“%d%s”?在有效字符串后添加额外字符并不是一个错误。我发现在这里您甚至不需要测试
1!=res
就好像字符串已被完全使用一样
string[n]
将指向
'\0'
在另一种情况下,无论哪个值具有
res
都将是错误的。我说得对吗?@likern首先在
中测试
res
。。。1 != res | | string[n]!='\0'
,我们知道
字符串[n]!='\仅当
res
的值为1时,才会执行0'
。所以我们知道扫描转换是通过
“%”SCNu32
完成的。在
“%n”
中的
上,扫描转换从不停止,因此已知扫描范围
“%n”
n
具有合法值。如果
res<1
,则扫描从未通过
“%”SCNu32
,因此
sscanf()
未设置
n
。但也许我没领会你的意思?不,也许我错了。我想我可以删除
1!=当
字符串[n]!='\使用了0'
。@likern代码可以通过
int n=0跟随您的新想法
和以后的
如果(0!=errno | | n>0 | | string[n]!='\0')
这样做不会节省太多,并且会丢失EOF检测。你的
如果(…||1!=res | |…)
更好。我看到这里你甚至不需要测试
1!=res
就好像字符串已被完全使用一样
string[n]
将指向
'\0'
在另一种情况下,无论哪个值具有
res
都将是错误的。我说得对吗?@likern首先在
中测试
res
。。。1 != res | | string[n]!='\0'
,我们知道
字符串[n]!='\仅当
res
的值为1时,才会执行0'
。所以我们知道扫描转换是通过
“%”SCNu32
完成的。在
“%n”
中的
上,扫描转换从不停止,因此已知扫描范围
“%n”
n
具有合法值。如果
res<1
,则扫描从未通过
“%”SCNu32
,因此
sscanf()
未设置
n
。但也许我没领会你的意思?不,也许我错了。我想我可以删除
1!=当
字符串[n]!='\使用了0'
。@likern代码可以通过
int n=0跟随您的新想法
和以后的
如果(0!=errno | | n>0 | | string[n]!='\0')
这样做不会节省太多,并且会丢失EOF检测。你的
如果(…|||1!=res | |…)
更好。