You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ try/catch程序无法触发第二个catch块问题求助

C++输入验证异常捕获问题修复

问题描述

编写了一个处理用户输入的try/catch程序,要求输入1-4的数字,需分别处理非数字输入(抛出std::invalid_argument)和超出范围输入(抛出std::out_of_range)。但测试超出范围输入时,总是触发std::invalid_argument的捕获逻辑,无法正确触发std::out_of_range的catch块。

原代码:

// C++
/*For context, choice is an integer from
User input that is supposed to be a number 1-4.*/

void search() {
    int choice;
    std::cout << "Search by:\n1:Title\n2:Year\n3:Actor\n4:Rating\n";
    
    try {
        std::cin >> choice;
        if(!isdigit(choice)) {
            throw std::invalid_argument("Please type a number. \n");
        } 
        if(choice >= 5 || choice <= 1) {
            throw out_of_range("Please input a number between 1 and 4");
        }
    }
    catch(std::out_of_range const& e){
        std::cout << e.what();
        cin.clear();
    }
    catch(std::invalid_argument const& e) {
        std::cout << e.what();
    }
}

错误原因分析

  1. isdigit用法错误:isdigit用于判断字符的ASCII值是否为数字(比如字符'1'的ASCII码是49,isdigit(49)才会返回真),但这里choice是int类型,存储的是输入数字的数值(比如输入1时,choice是1),isdigit(1)判断的是ASCII码1对应的字符,不是数字,所以会错误触发std::invalid_argument。
  2. 非数字输入处理逻辑缺失:当用户输入非数字时,std::cin >> choice会执行失败,此时choice值未定义,且cin会进入错误状态,后续的范围判断逻辑完全混乱。
  3. 范围判断条件错误:choice <= 1会把合法输入1也判定为超出范围,应该改为choice < 1。
  4. out_of_range缺少命名空间前缀:未加std::前缀会导致编译错误(除非全局引入了std命名空间)。

修正后的代码

#include <iostream>
#include <stdexcept>
#include <limits> // 用于清除输入缓冲区

void search() {
    int choice;
    std::cout << "Search by:\n1:Title\n2:Year\n3:Actor\n4:Rating\n";
    
    try {
        // 检查输入是否为有效整数
        if (!(std::cin >> choice)) {
            // 清除cin的错误状态
            std::cin.clear();
            // 忽略缓冲区中剩余的无效输入,避免影响后续操作
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            throw std::invalid_argument("Please type a number.\n");
        }

        // 检查输入范围是否在1-4之间
        if (choice < 1 || choice > 4) {
            throw std::out_of_range("Please input a number between 1 and 4.\n");
        }

        // 输入合法时的后续逻辑
        std::cout << "Valid choice: " << choice << "\n";
    }
    catch (const std::out_of_range& e) {
        std::cout << e.what();
    }
    catch (const std::invalid_argument& e) {
        std::cout << e.what();
    }
}

int main() {
    search();
    return 0;
}

修正要点说明

  • 用std::cin >> choice的返回值判断输入是否有效,替代错误的isdigit判断逻辑。
  • 输入无效时,先清除cin错误状态并忽略缓冲区垃圾数据,避免影响后续输入操作。
  • 修正范围判断条件,确保1-4为合法输入区间。
  • 给out_of_range添加std::前缀,符合标准库命名规范。

内容的提问来源于stack exchange,提问作者Kohaya3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:55:31