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
相关产品推荐
相关产品推荐

