C语言中从字符串提取数字的方法及异常处理问询
用sscanf提取UART字符串中的数字并做格式校验
当然有更简便的sscanf用法!你的需求刚好适合用sscanf的格式匹配直接完成提取,比你说的strtok+手动截字符+转换要省心太多,而且还能顺便做格式校验。
先直接给你针对目标字符串的写法,假设你的输入字符串是char input_str[] = "43.533a,5532":
float num1; int num2; // 关键就是这个格式字符串:%fa,%d int match_count = sscanf(input_str, "%fa,%d", &num1, &num2);
为什么这行代码能工作?
%f会自动匹配开头的浮点数部分(43.533),直到遇到非数字/小数点的字符(也就是那个a);- 后面的
a是格式字符串里的固定匹配项,确保第一个数字后面确实跟着a; - 逗号是固定分隔符匹配,最后
%d提取后面的整数5532。
如果你的场景里,第一个数字后面的字符不一定是a,只是任意非数字的结束符,那可以把格式字符串改成"%f,%d"——%f会自动停在第一个非数字/小数点的位置,照样能正确提取43.533,同时跳过后面的字符直到匹配到逗号。
格式异常的检测方法
sscanf的返回值是成功匹配并赋值的参数个数,这就是最直接的格式校验手段:
- 如果返回值是
2:说明两个数字都成功提取,格式完全符合预期; - 如果返回值是
1:说明第一个浮点数匹配成功,但后面的逗号或整数部分有问题(比如逗号丢失、后面不是整数); - 如果返回值是
0:说明连第一个浮点数都匹配失败(比如字符串开头不是数字); - 如果返回值是
EOF:说明输入字符串为空或有读取错误。
举几个异常场景的例子:
- 输入是
"43.533x,5532",用"%fa,%d"的话,a匹配失败,返回值是1; - 输入是
"abc,123",%f匹配失败,返回值是0; - 输入是
"43.533a,xyz",%d匹配失败,返回值是1; - 输入是
"43.533a"(没有逗号和后面的数字),返回值是1。
如果需要更严格的校验,比如确保字符串里只有这两个部分、没有多余字符,还可以在格式字符串末尾加%n来记录匹配到的位置,然后检查这个位置是否等于字符串长度:
int pos; int match_count = sscanf(input_str, "%fa,%d%n", &num1, &num2, &pos); if (match_count == 2 && pos == strlen(input_str)) { // 完全匹配,没有多余字符 } else { // 格式异常,可能有多余字符 }
和你原思路的对比
你原来的方法需要:
- 用
strtok按逗号拆分; - 手动截取第一个字符串的前n-1个字符;
- 调用
atof/atoi转换; - 还要自己处理拆分失败、字符串长度不足的情况。
而用sscanf的话,一步就能完成提取+初步校验,代码更简洁,逻辑更清晰,出错概率也更低。
内容的提问来源于stack exchange,提问作者po.pe
相关产品推荐
相关产品推荐

