You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动