用find_first_not_of("0")定位首非零字符下标并substr截取,可高效去除前导零;需处理全零串返回"0"或空串,且须考虑负号、小数点及非数字字符等边界情况。

用 find_first_not_of 定位第一个非零字符位置
直接删开头的零,本质是找第一个不是 '0' 的字符下标,再从那里开始截取。C++ 标准库的 string::find_first_not_of 正好干这事——它返回第一个不匹配指定字符集的位置,传 "0" 就行。
- 如果整个字符串全是
'0'(比如"000"),find_first_not_of("0")返回string::npos,得手动处理成保留一个'0'还是变空串,看业务需求 - 注意:只删前导零,中间或末尾的
'0'不动,比如"001020"→"1020" - 别用
erase(0, n)配合循环删第一个字符,效率低,且容易越界
用 substr 截取,避免修改原字符串
拿到起始位置后,优先用 substr 构造新字符串,而不是在原串上 erase。前者语义清晰、无副作用,也方便链式调用。
- 示例:
auto trimmed = s.substr(s.find_first_not_of("0"));—— 但这里没判npos,实际要用三元运算符兜底 - 更稳妥写法:
s.find_first_not_of("0") == string::npos ? "0" : s.substr(s.find_first_not_of("0")) - 如果原字符串是
const或来自只读上下文(比如函数参数),substr是唯一安全选择
数字字符串转整数再转回?小心溢出和格式丢失
有人图省事用 stoi / stoll 转数字再 to_string,这在小整数时看似可行,但隐患明显:
- 输入超
long long范围(如"00012345678901234567890")会抛std::out_of_range - 带前导零的十六进制或八进制字符串(如
"0x00FF"、"00123")会被误当十进制解析,结果错乱 - 原始字符串可能含非数字字符(如
"000abc"),stoi只取前缀, silently 截断,行为难预料
处理空串、全零、负号等边界情况
真实数据常带干扰,不能只盯着纯数字串。比如 ""、"-00123"、"+000"、"000.001" 这些都得按需分类处理。
立即学习“C++免费学习笔记(深入)”;
- 空串:
find_first_not_of返回npos,直接返回空串或报错,别硬截 - 负号/正号:先检查首字符是否为
'-'或'+',再对后续子串去零,否则"-00123"会变成"-123"(正确),但"-000"应该是"0"还是"-0"?取决于你是否要保留符号语义 - 小数点:若字符串是浮点格式(如
"000.123"),前导零规则不同——小数点前的零可删,小数点后的不行,得拆开处理
真正鲁棒的实现,得先明确输入契约:是纯十进制整数?是否允许符号?是否支持小数?没想清楚就套通用逻辑,很容易漏 case。


















