使用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 | |…)
更好。