std::stoi能否识别超出基数范围的数字并抛出异常?
根因说明
std::stoi的默认解析逻辑是从字符串首部开始匹配有效字符,遇到第一个不符合当前基数规则的字符时立即终止解析,只要成功解析到至少1个有效字符,就不会抛出std::invalid_argument异常。
你传入的0xgg触发的解析逻辑为:base设为0时自动识别到前缀0x判定为十六进制,前缀后的第一个字符g不属于十六进制有效字符(十六进制有效字符为0-9、a-f、A-F),因此仅解析到前缀对应的数值0直接返回,不会触发异常。
解决方案
利用std::stoi的第二个输出参数pos,该参数会返回解析终止的下标位置,只需校验该位置是否等于字符串总长度,即可判断是否存在无效后缀字符,存在时主动抛出异常即可。
修改后的代码示例:
#include <stdexcept> #include <string> int ConvertToInt(const std::string& aVal) { std::size_t parsedEndPos = 0; int lVal = std::stoi(aVal, &parsedEndPos, 0); // 校验是否完整解析整个字符串 if (parsedEndPos != aVal.size()) { throw std::invalid_argument("input contains invalid characters for current base"); } return lVal; }
效果验证
该方案完全保留了你原本自动识别十进制/十六进制的能力,同时可拦截所有带无效后缀的输入:
- 合法输入
"123"、"0x1f"会完整解析,正常返回对应数值 - 非法输入
"0xgg"、"123a"、"0x12z"会因未解析完整个字符串抛出异常,符合你的预期。
如果需要额外禁止字符串开头带空白字符(std::stoi默认会跳过开头空白),可以在校验前额外判断字符串首字符是否为空白即可。
内容的提问来源于stack exchange,提问作者tenslw
相关产品推荐
相关产品推荐

