C++编写ReadDouble函数如何校验千分位逗号的合法输入位置
输入1.2输出12的问题原因
你现有代码中只有数字字符会被追加到convert转换字符串,小数点字符的处理分支没有将.加入convert。而首字符为.时会在初始化阶段就加入convert,所以.2可以正常输出,1.2的小数点被过滤,转换后就变成了12。
千分位校验与小数点后逗号限制的实现
实现逻辑如下:
- 增加
has_decimal标记,一旦检测到小数点,后续所有字符只要出现逗号直接判定非法 - 整数部分(小数点前、跳过正负号)从右往左遍历,每3个数字允许出现1个逗号,不符合规则直接判定非法
- 所有合法的数字、小数点都要加入到转换字符串中,逗号仅校验合法性,不加入转换字符串
修改后的完整代码:
#include <iostream> #include <cstdlib> #include <string> #include <algorithm> using namespace std; double ReadDouble(string prompt); double ReadDouble(string prompt) { string input; string convert; bool isValid; do { isValid = true; convert.clear(); cout << prompt; cin >> input; int start_idx = 0; // 校验首字符合法性 if (input[0] != '+' && input[0] != '-' && input[0] != '.' && !isdigit(input[0])) { cout << "Error! Invalid first character.\n"; isValid = false; continue; } // 跳过正负号 if (input[0] == '+' || input[0] == '-') { convert += input[0]; start_idx = 1; } // 拆分整数和小数部分 size_t dot_pos = input.find('.', start_idx); string int_part = input.substr(start_idx, (dot_pos == string::npos ? input.length() - start_idx : dot_pos - start_idx)); string dec_part = (dot_pos == string::npos ? "" : input.substr(dot_pos + 1)); // 校验整数部分千分位合法性 int digit_count = 0; for (int i = int_part.length() - 1; i >= 0; i--) { if (int_part[i] == ',') { if (digit_count != 3) { cout << "Error! Comma not in valid thousandth position.\n"; isValid = false; break; } digit_count = 0; } else if (isdigit(int_part[i])) { digit_count++; convert += int_part[i]; } else { cout << "Error! Invalid character in integer part.\n"; isValid = false; break; } } if (!isValid) continue; // 反转整数部分恢复顺序 reverse(convert.begin() + start_idx, convert.end()); // 校验小数点和小数部分 if (dot_pos != string::npos) { convert += '.'; // 校验小数部分不能有逗号 for (char c : dec_part) { if (c == ',') { cout << "Error! Comma not allowed after decimal point.\n"; isValid = false; break; } else if (!isdigit(c)) { cout << "Error! Invalid character in decimal part.\n"; isValid = false; break; } convert += c; } } if (!isValid) continue; // 校验仅存在一个小数点 if (input.find('.', dot_pos + 1) != string::npos) { cout << "Error! Only one decimal point allowed.\n"; isValid = false; } } while (!isValid); return atof(convert.c_str()); } int main() { double x = ReadDouble("Enter a value: "); cout << "Value entered was " << x << endl; return 0; }
内容的提问来源于stack exchange,提问作者pa_dead
相关产品推荐
相关产品推荐

