C++中std::stoi抛出std::invalid_argument异常问题求助(《C++编程原理与实践》第4章练习17场景)
问题分析与解决
咱们先来拆解你遇到的两个核心问题:
1. std::invalid_argument异常的根源
你用std::cin >> input读取输入时,当你输入|,这个字符会被完整读取到input字符串里,接着调用std::stoi(input)尝试把|转换成整数——这显然是不可能的,因为|不是有效的数字字符,所以标准库直接抛出了std::invalid_argument异常。
而你的测试代码能正常运行,是因为你传入的是合法的数字字符串"4",完全符合stoi的转换要求,自然不会触发异常。
2. 代码的逻辑错误
另外,你的sequence.push_back(intInput);写在了while循环的外面,这意味着不管你输入多少个数字,最终只有最后一次转换的intInput会被添加到vector里,之前的所有输入都被丢弃了,这根本没法完成后续的众数、最值计算。
修正后的代码方案
这里给你两种可行的修正思路,你可以根据需求选择:
思路一:直接读取int类型(更简单)
既然我们要的是整数序列,不如直接让cin读取int类型,当输入非整数(比如|)时,cin会进入错误状态,循环自动终止,这样就不需要手动用stoi转换,也能避免异常:
#include <iostream> #include <string> #include <vector> // 先占位findMode函数,后续补全实现 int findMode(const std::vector<int>& seq) { // 这里是你后续要实现的众数逻辑 return 0; } int main() { std::vector<int> sequence {}; int intInput {}; std::cout << "Enter a sequence of numbers (enter a non-number to stop):\n> "; // 直接读取int,输入非数字时循环终止 while (std::cin >> intInput) { sequence.push_back(intInput); } // 检查vector是否为空,避免后续操作出错 if (sequence.empty()) { std::cout << "No valid numbers entered!\n"; return 1; } std::cout << "The mode is: " << findMode(sequence) << '\n'; // 额外补充最值计算的示例代码 int min_val = sequence[0]; int max_val = sequence[0]; for (int num : sequence) { if (num < min_val) min_val = num; if (num > max_val) max_val = num; } std::cout << "The minimum value is: " << min_val << '\n'; std::cout << "The maximum value is: " << max_val << '\n'; return 0; }
思路二:保留字符串读取,捕获转换异常
如果你坚持要用字符串读取的方式(比如需要做更多输入校验),可以在转换时捕获std::invalid_argument异常,以此作为输入终止的信号:
#include <iostream> #include <string> #include <vector> #include <stdexcept> int findMode(const std::vector<int>& seq) { return 0; } int main() { std::vector<int> sequence {}; std::string input {}; std::cout << "Enter a sequence of numbers (enter '|' to stop):\n> "; while (std::cin >> input) { try { int intInput = std::stoi(input); sequence.push_back(intInput); } catch (const std::invalid_argument& e) { // 如果是输入了|或者其他非数字,终止循环 if (input == "|") { break; } else { std::cout << "Invalid number! Please enter a valid integer or '|' to stop:\n> "; } } } if (sequence.empty()) { std::cout << "No valid numbers entered!\n"; return 1; } std::cout << "The mode is: " << findMode(sequence) << '\n'; // 最值计算 int min_val = sequence[0]; int max_val = sequence[0]; for (int num : sequence) { min_val = std::min(min_val, num); max_val = std::max(max_val, num); } std::cout << "The minimum value is: " << min_val << '\n'; std::cout << "The maximum value is: " << max_val << '\n'; return 0; }
额外提示
- 不管用哪种方案,都要记得检查
sequence是否为空,避免后续对空vector的操作(比如访问sequence[0])导致未定义行为。 - 你的
findMode函数还没实现,后续补全时要注意处理vector为空、多个众数的情况哦。
内容的提问来源于stack exchange,提问作者SILO




