如何检测字符串转换为float/uint64_t时的数值溢出异常
字符串转数值的溢出捕获方法
strtoull、strtof等C标准库字符串转数值函数,本身就有标准的溢出判定规则,不需要手动比对字符串长度做预判,直接用库自带的状态标识即可实现准确判断。
注意所有转换操作前必须包含必要头文件:<stdlib.h>、<stdint.h>、<errno.h>,浮点转换额外需要<math.h>。
uint64_t 类型转换的溢出判断
你现有代码的逻辑框架是对的,只需要补充errno校验即可,注意调用转换函数前必须手动将errno置为0——errno不会被库函数主动清空,残留的历史错误值会导致误判。
参考实现:
char *t; // 你的输入字符串指针 char *endptr; uint64_t cn; errno = 0; cn = strtoull(t, &endptr, 10); // 捕获溢出 if (errno == ERANGE) { // 此处写溢出处理逻辑:输入数值超出uint64_t存储范围 // 上溢时函数固定返回UINT64_MAX,也就是你观察到的18446744073709551615 } // 可选补充:校验字符串是否为纯合法数字(排除夹杂字母、符号的非法输入) if (*endptr != '\0') { // 此处写非法格式处理逻辑 }
float 类型转换的溢出判断
首先修正你代码里的笔误:strtof的第二个参数要求是char**类型,你传入vv(char*类型)属于未定义行为,正确写法应该传入&vv。
浮点转换的溢出判断逻辑和整数一致,同样依赖errno标识,上溢时函数会返回HUGE_VALF(正溢出为正的极大值/正无穷,负溢出为负的极小值/负无穷),下溢(数值过小无法表示为非零float)时返回0,两种情况都会将errno置为ERANGE。
参考实现:
char *tt; // 你的输入字符串指针 char *endptr_f; float cn2; errno = 0; cn2 = strtof(tt, &endptr_f); // 捕获溢出 if (errno == ERANGE) { // 此处写溢出处理逻辑,可通过返回值进一步区分上溢/下溢: // 返回HUGE_VALF或-HUGE_VALF为上溢,返回0为下溢 } // 可选补充:校验字符串是否为合法浮点格式 if (*endptr_f != '\0') { // 此处写非法格式处理逻辑 }
注意事项
- 不要仅通过返回值等于
UINT64_MAX或HUGE_VALF判定溢出,合法输入完全可能刚好等于这些极值,必须配合errno == ERANGE的判断才能保证准确性。 - errno是线程局部变量,多线程环境下上述判断逻辑依然安全,不会出现跨线程错误值干扰。
- 如果不需要区分上溢、下溢,只要判断是否超出类型可表示范围,直接判断
errno == ERANGE即可。
内容的提问来源于stack exchange,提问作者stht55
相关产品推荐
相关产品推荐

