You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 06:18:02