字符串提取long long整数至vector的代码异常排查与调整求助
问题分析与解决方案
问题1:特定输入触发std::invalid_argument异常
原因
你当前的实现应该是按空格分割输入字符串,再对每个子串直接调用std::stoll。但这种方式无法处理类似"123-123"、"123-"的子串:
std::stoll要求输入字符串必须是完整有效的数字格式(可选符号位+连续数字),当子串中出现数字后接非数字字符(比如"123-"里的-),或者中间插入符号(比如"123-123"里的-),函数会直接抛出std::invalid_argument异常终止程序。- 你的期望逻辑是:符号位仅作为数字的前缀(
-必须紧跟数字才视为负号),遇到非数字字符时结束当前数字提取,因此"123-123"应拆分为123和-123,"123-"仅提取123。
解决方案
放弃按空格分割的方式,改为逐字符扫描识别有效数字的起始和结束:
- 跳过所有空白字符;
- 遇到
-时,检查下一个字符是否为数字:是则将其视为负号,开始提取数字;否则跳过该-; - 遇到数字时,持续收集后续连续的数字字符,形成有效数字字符串;
- 对有效字符串调用
std::stoll,避免处理无效格式的子串。
问题2:超大数字提示文本错误
原因
你的代码在捕获std::out_of_range异常(数字超出long long范围)时,输出的提示字符串不符合要求,只需修改该提示内容即可。
完整实现代码
#include <vector> #include <string> #include <stdexcept> #include <cctype> #include <cstdio> std::vector<long long> extractLongLongs(const std::string& input) { std::vector<long long> nums; size_t pos = 0; const size_t inputLen = input.size(); while (pos < inputLen) { // 跳过空白字符 while (pos < inputLen && std::isspace(static_cast<unsigned char>(input[pos]))) { ++pos; } if (pos >= inputLen) break; size_t numStart = pos; // 处理负号:仅当负号后紧跟数字时,视为有效符号 if (input[pos] == '-' && pos + 1 < inputLen && std::isdigit(static_cast<unsigned char>(input[pos+1]))) { ++pos; } // 收集连续的数字字符 while (pos < inputLen && std::isdigit(static_cast<unsigned char>(input[pos]))) { ++pos; } // 验证是否为有效数字(排除单独的'-') if (pos > numStart && !(numStart == pos - 1 && input[numStart] == '-')) { std::string numStr = input.substr(numStart, pos - numStart); try { long long num = std::stoll(numStr); nums.push_back(num); } catch (const std::out_of_range&) { // 输出要求的提示文本 printf("Number too big!\n"); // 若需遇到超大数字时终止程序,可添加 return nums; 或 exit(1); } // std::invalid_argument 在此逻辑下基本不会触发,可省略捕获 } else { // 跳过无效的单独'-' ++pos; } } return nums; }
代码说明
- 逐字符扫描确保只提取有效数字格式,避免了
std::invalid_argument异常; - 对超大数字捕获
std::out_of_range异常,输出指定提示; - 测试输入
"-123 123-123 123- 123"时,会正确提取出-123、123、-123、123。
内容的提问来源于stack exchange,提问作者tom anthony
相关产品推荐
相关产品推荐

