#include <iostream>
#include <stdexcept> // 标准异常类头文件
#include <string>
#include <cstring> // 用于 strcpy/strlen(处理C风格字符串)
// 自定义异常类:非法操作符异常(直接继承自 std::exception 基类)
class InvalidOperatorException : public std::exception {
private:
// 存储异常信息(用C风格字符串,符合 what() 返回 const char* 的要求)
char error_msg[100];
public:
// 构造函数:拼接异常信息并存储到 error_msg
explicit InvalidOperatorException(const std::string& op) {
std::string msg = "非法操作符:" + op + ",仅支持 +、-、*、/、%";
// 复制字符串到成员变量(避免临时对象析构导致野指针)
strncpy(error_msg, msg.c_str(), sizeof(error_msg) - 1);
error_msg[sizeof(error_msg) - 1] = '\0'; // 确保字符串结束符
}
// 重写基类的 what() 虚函数(必须实现)
// noexcept 表示该函数不会抛出异常(C++11 推荐)
const char* what() const noexcept override {
return error_msg; // 返回异常描述信息
}
};
// 自定义异常类:除0异常(直接继承自 std::exception 基类)
class DivideByZeroException : public std::exception {
private:
char error_msg[100];
public:
// 构造函数:区分除法/取模的除0场景
explicit DivideByZeroException(const std::string& op) {
std::string msg = "运算错误:" + op + " 操作中除数/模数不能为 0";
strncpy(error_msg, msg.c_str(), sizeof(error_msg) - 1);
error_msg[sizeof(error_msg) - 1] = '\0';
}
// 重写基类的 what() 虚函数
const char* what() const noexcept override {
return error_msg;
}
};
// 计算器核心函数:逻辑完全不变
double calculate(double num1, double num2, const std::string& op) {
if (op == "+") {
return num1 + num2;
} else if (op == "-") {
return num1 - num2;
} else if (op == "*") {
return num1 * num2;
} else if (op == "/") {
if (num2 == 0) {
throw DivideByZeroException("/");
}
return num1 / num2;
} else if (op == "%") {
if (num2 == 0) {
throw DivideByZeroException("%");
}
return static_cast<int>(num1) % static_cast<int>(num2);
} else {
throw InvalidOperatorException(op);
}
}
int main() {
double num1, num2;
std::string op;
std::cout << "===== C++ 简易计算器 =====" << std::endl;
std::cout << "支持运算:+、-、*、/、%" << std::endl;
std::cout << "输入格式:数字1 操作符 数字2(示例:10 + 5)" << std::endl;
std::cout << "输入 'q' 退出程序" << std::endl;
while (true) {
std::cout << "\n请输入计算式:";
if (!(std::cin >> num1)) {
std::cin.clear();
std::string quit;
std::cin >> quit;
if (quit == "q" || quit == "Q") {
std::cout << "程序退出!" << std::endl;
break;
} else {
std::cerr << "输入错误:第一个值不是有效数字!" << std::endl;
continue;
}
}
std::cin >> op >> num2;
try {
double result = calculate(num1, num2, op);
std::cout << "计算结果:" << num1 << " " << op << " " << num2 << " = " << result << std::endl;
}
// 捕获自定义异常(继承自 std::exception,多态生效)
catch (const DivideByZeroException& e) {
std::cerr << "错误:" << e.what() << std::endl;
}
catch (const InvalidOperatorException& e) {
std::cerr << "错误:" << e.what() << std::endl;
}
// 捕获所有 std::exception 子类(兜底)
catch (const std::exception& e) {
std::cerr << "未知错误:" << e.what() << std::endl;
}
catch (...) {
std::cerr << "严重错误:发生未预期的异常!" << std::endl;
}
}
return 0;
}
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com