C++银行程序实现货币金额输入校验的最优方案是什么?
问题分析与优化方案
你当前的实现存在几个明显的缺陷,完全无法满足货币校验要求:
- 用
std::stoi(字符串转整型)解析货币值,只要输入带小数就会直接截断小数部分,比如输入100.99只会得到100,金额直接出错- 完全没有校验小数位数,不符合要求的保留2位小数规则
- 只捕获了
std::invalid_argument异常,没有处理std::out_of_range异常,输入数值超出范围时会直接崩溃
满足需求的精简实现
你明确要求接收double类型参数的前提下,以下实现已经覆盖所有校验规则,同时兼容浮点数精度误差问题:
#include <iostream> #include <string> #include <stdexcept> #include <cmath> #include <iomanip> void handleDeposit(const std::string& userInput) { try { // 改用stod转double,完整保留小数部分 double amount = std::stod(userInput); // 非负校验 if (amount < 0) { throw std::invalid_argument("金额不能为负"); } // 2位小数校验:乘100取整后与原值比较,误差小于1e-6视为合法 const double precisionEps = 1e-6; double scaledAmount = amount * 100.0; if (std::abs(scaledAmount - std::round(scaledAmount)) > precisionEps) { throw std::invalid_argument("金额最多保留2位小数"); } // 调用实际存款逻辑 std::cout << std::fixed << std::setprecision(2) << "你已成功存入 " << amount << " 元到账户" << std::endl; } catch (const std::invalid_argument&) { std::cout << "输入无效:请输入合法货币金额(最多2位小数的非负数)" << std::endl; } catch (const std::out_of_range&) { std::cout << "输入无效:金额超出可处理范围" << std::endl; } }
额外优化建议
如果业务规则允许调整参数类型,更推荐用整型单位「分」存储金额,完全规避浮点数精度误差问题,校验逻辑也会更简单:只需要校验输入字符串符合最多2位小数的格式,直接转成整数分做后续运算即可,不会出现0.1+0.2≠0.3的精度异常。
内容的提问来源于stack exchange,提问作者mathewsjoyy
相关产品推荐
相关产品推荐

