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

C++中字符串与浮点数的异常处理错误排查

问题:C++薯球程序异常处理失效

我编写了一个关于薯球的C++程序,但异常处理功能无法正常工作。当输入字符串或浮点数等非法值时,程序未触发错误提示,反而执行了if (DaysNumber < 7)分支的输出。以下是主文件代码:

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <stdexcept>
#include "tatertot.h"

using namespace std;

int main() {
    int DaysNumber;
   
    // 询问用户上次吃薯球距今多久
    cout << "How long has it been since you had some yummy tots?" << endl;
    cout << "Enter the number of days: " << endl;
    cin >> DaysNumber;

    // 处理无效输入
    try {
        // 如果用户已经一周或更久没吃薯球
        if (DaysNumber >= 7) {
            cout << "Yay! I bet those tots were delicious. Here's a recipe to try next time you want to eat tater tots: " << endl;
            cout << "https://www.allrecipes.com/recipe/236749/tater-tots-nachos/";
            abort();
        }

        // 如果用户最近刚吃过薯球
        else {
            cout << "It. Is. TATER TOT TIME!" << endl;
            cout << "Go enjoy some yummy tots!" << endl;
            cout << "https://www.allrecipes.com/recipe/236749/tater-tots-nachos/";
            abort();
        }

    }
    catch (string e) {
        cin.clear();
        cout << "I'm sorry, but your input is invalid. Could you please try again?" << endl;
        cin >> DaysNumber;
    }

    catch (double e) {
        cin.clear();
        cout << "I'm sorry, but your input is invalid. Could you please try again?" << endl;
        cin >> DaysNumber;
    }
    return 0;
};

我尝试过其他异常处理方法,也在类文件和访问器-修改器文件中定义过DaysNumber,但都没有效果。请问我遗漏了什么问题?


问题分析与解决方案

核心问题

  • 输入失败不会自动抛异常:默认情况下,cin >> DaysNumber遇到非法输入时,只会设置failbit状态位,不会抛出string或double类型的异常,你的catch块永远不会被触发。
  • 非法输入后变量值无定义:输入失败时,DaysNumber是未初始化的垃圾值,程序会随机进入if或else分支,这就是错误分支执行的原因。
  • 异常捕获类型错误:C++标准IO操作失败时,若开启异常,抛出的是std::ios_base::failure类型,而非string或double。
  • abort()误用:abort()会直接终止程序,即使捕获到错误,后续重新输入的逻辑也无法执行。

修复方案

方案1:直接检查输入状态(常用方式)

#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
#include "tatertot.h"

using namespace std;

int main() {
    int DaysNumber;
    bool validInput = false;

    while (!validInput) {
        cout << "How long has it been since you had some yummy tots?" << endl;
        cout << "Enter the number of days: " << endl;
        
        if (cin >> DaysNumber) {
            validInput = true;
            if (DaysNumber >= 7) {
                cout << "Yay! I bet those tots were delicious. Here's a recipe to try next time you want to eat tater tots: " << endl;
                cout << "薯球玉米片食谱";
            } else {
                cout << "It. Is. TATER TOT TIME!" << endl;
                cout << "Go enjoy some yummy tots!" << endl;
                cout << "薯球玉米片食谱";
            }
        } else {
            cin.clear(); // 清除错误状态
            cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清空缓冲区错误内容
            cout << "I'm sorry, but your input is invalid. Could you please try again?" << endl;
        }
    }
    return 0;
};

方案2:启用输入异常并捕获正确类型

#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
#include <stdexcept>
#include "tatertot.h"

using namespace std;

int main() {
    int DaysNumber;
    bool validInput = false;

    // 设置cin在failbit触发时抛出异常
    cin.exceptions(ios::failbit);

    while (!validInput) {
        try {
            cout << "How long has it been since you had some yummy tots?" << endl;
            cout << "Enter the number of days: " << endl;
            cin >> DaysNumber;

            validInput = true;
            if (DaysNumber >= 7) {
                cout << "Yay! I bet those tots were delicious. Here's a recipe to try next time you want to eat tater tots: " << endl;
                cout << "薯球玉米片食谱";
            } else {
                cout << "It. Is. TATER TOT TIME!" << endl;
                cout << "Go enjoy some yummy tots!" << endl;
                cout << "薯球玉米片食谱";
            }
        } catch (const ios_base::failure& e) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "I'm sorry, but your input is invalid. Could you please try again?" << endl;
        }
    }
    return 0;
};

关键注意点

  • 处理输入失败时,必须用cin.ignore()清空缓冲区,否则错误输入会一直留在缓冲区,导致后续输入循环重复失败。
  • 避免使用abort(),正常逻辑中应允许用户重新输入,而非强制终止程序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:30:32