直接用 static_cast 转换 ascii 数字字符不安全,会得到 ascii 码而非数字值;正确做法是先校验 c >= '0' && c

直接用 static_cast 转换 ASCII 数字字符
只有当 char 真的是表示数字的 ASCII 字符(比如 '0' 到 '9')时,才能安全转成对应整数值。最常见错误是直接 static_cast<int>(c)</int>,结果得到的是 ASCII 码('5' 变成 53),而不是数字 5。
- 正确做法:减去
'0'——int num = c - '0'; - 必须先校验范围:
if (c >= '0' && c ,否则越界行为未定义 -
static_cast在这里没实际作用,c - '0'本身就会提升为int,硬套反而掩盖意图
处理字符串形式的整数(如 "123")用 std::stoi
如果输入是 char* 或 std::string,不是单个字符,那本质是字符串解析问题,不能用减 '0' 的方式。
-
std::stoi("123")返回int,但遇到非法字符(如"12a3")会抛std::invalid_argument - 要捕获异常或检查剩余字符,可用
std::strtol更细粒度控制:char* end; long v = std::strtol(s, &end, 10);,然后检查*end是否为'\0' -
std::stoi不支持指定进制以外的容错,比如空格开头或溢出时直接抛std::out_of_range
避免 atoi:无错误反馈、不推荐用于新代码
atoi 看起来简单,但完全无法区分成功和失败 —— atoi("abc") 和 atoi("0") 都返回 0。
- 它不设置
errno,也不提供解析结束位置,出错时静默失败 - C++ 标准明确建议用
std::stoi或std::strtol替代 - 尤其在嵌入式或金融类逻辑中,这种“假装成功”的行为极易埋下隐患
宽字符或 Unicode 场景下不能直接减 '0'
如果 char 实际来自 UTF-8 编码的多字节序列(比如汉字‘一’),或者你用的是 wchar_t,那么 c - '0' 完全无效,甚至触发未定义行为。
- UTF-8 中数字字符仍是单字节,所以
'0'~'9'没问题;但任意char不能假设是 ASCII - 真正需要处理 Unicode 数字(如全角数字‘1’)时,得用 ICU 或
std::locale相关 API,不是简单算术运算 - 跨平台代码里,别依赖
char的符号性——显式用unsigned char转换再参与计算更稳妥
实际写的时候,先盯住输入来源:是单个 ASCII 数字字符?还是零终止字符串?有没有错误容忍要求?这几个判断点选错了,后面所有转换都白搭。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











