C++如何通过ASCII码比较int/double与char?计算器功能实现问题
问题解答:带撤销功能的计算器输入异常问题
为什么不能直接用double变量和字母比较
- 你使用
cin >> double类型变量时,如果输入内容是无法解析为数值的字母,输入流会立即进入失败状态,不会将字母的ASCII码写入目标double变量,后续所有输入操作都会直接失效,这就是你输入u后程序异常的核心原因。C++的类型化输入是严格匹配类型的,不存在自动将字母的ASCII存入double变量的逻辑,因此你直接比较double变量和字符'u'的操作不可能生效。
正确的实现方案
核心思路是先统一按字符串读取第一个输入,先判断是否为撤销指令,再做后续处理,修改步骤如下:
- 循环中第一个输入不直接用double接收,改为用
string类型接收 - 优先判断输入内容是否为
u/U,如果是直接执行撤销逻辑,无需读取后续运算符 - 若不是撤销指令,再将字符串转换为double类型的数值,再正常读取运算符执行计算
- 补充异常边界判断:历史记录为空时禁止撤销、除法操作校验除数不为0、撤销后要弹出历史栈顶避免重复撤销同一个值
修改后的参考代码
#include <iostream> #include <list> #include <string> #include <stdexcept> using namespace std; int main() { // 'value'为最终计算结果 double value = 0; double user; char operation; // 历史计算值记录 list<double> history; // 展示初始值(0) cout << "=>" << value << endl; while(true) { string first_input; cin >> first_input; // 先判断是否为撤销指令 if (first_input == "u" || first_input == "U") { if (history.empty()) { cout << "=> 没有可撤销的操作" << endl; continue; } value = history.front(); history.pop_front(); // 撤销后弹出栈顶,下次撤销取更早的记录 cout << "=>" << value << endl; continue; // 撤销操作不需要读取后续运算符,直接进入下一轮循环 } // 不是撤销指令,尝试转成double数值 try { user = stod(first_input); } catch (const invalid_argument&) { cout << "=> 输入不合法,请输入数字或者u/U执行撤销" << endl; // 清空输入缓冲区错误状态和残留内容 cin.clear(); cin.ignore(1024, '\n'); continue; } // 正常读取运算符 cin >> operation; // 运算前先把当前值存入历史栈 history.push_front(value); switch(operation) { case '+': value += user; break; case '-': value -= user; break; case '*': value *= user; break; case '/': if (user == 0) { cout << "=> 除数不能为0" << endl; history.pop_front(); // 非法操作不需要保留历史 continue; } value /= user; break; default: cout << "=> 不支持的运算符" << endl; history.pop_front(); // 非法操作不需要保留历史 continue; } cout << "=>" << value << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Long Huang
相关产品推荐
相关产品推荐

