【问题标题】:C++ Numerical Input ValidationC++ 数字输入验证
【发布时间】:2020-10-08 03:43:04
【问题描述】:

我习惯了 Python,现在正在学习 C++,这对我来说有点复杂。如何修改输入以使其符合代码顶部注释中的描述?我试图包含 if (input[0]!='.' &&...) 但它只返回 0。我希望它作为数字的一部分包含在内。与输入的第一个字符之后的字符相同。

我也不知道如何用逗号分隔超过三位数的数字(显然是从数字的末尾开始)(所以 1000000 应该返回为 1,000,000)。

/*
    * The first character can be a number, +, -, or a decimal point
    * All other characters can be numeric, a comma or a decimal point
    * Any commas must be in their proper location (ie, separating hundreds from thousands, from millions, etc)
    * No commas after the decimal point
    * Only one decimal point in the number
    * 
*/

#include <iostream>
#include <cmath>
#include <climits>
#include <string>

int ReadInt(std::string prompt);

int ReadInt(std::string prompt)
{
    std::string input;
    std::string convert;
    bool isValid=true;

    do {
        isValid=true;

            std::cout << prompt;
            std::cin >> input;


        if (input[0]!='.' && input[0]!='+' && input[0]!='-' && isdigit(input[0]) == 0) {
            std::cout << "Error! Input was not an integer.\n";
            isValid=false;
        }
        else {
            convert=input.substr(0,1);
        }

        long len=input.length();
        for (long index=1; index < len && isValid==true; index++) {
            if (input[index]==',') {
                ;
            }
            else if (isdigit(input[index]) == 0){
                std::cout << "Error! Input was not an integer.\n";
                isValid=false;
            }
            else if (input[index] == '.') {
                ;
            }
            else {
                convert += input.substr(index,1);
            }
        }
        } while (isValid==false);


    int returnValue=atoi(convert.c_str());
        return returnValue;
}


int main()
{
    int x=ReadInt("Enter a value: ");
    std::cout << "Value entered was " << x << std::endl;
    return 0;
}

【问题讨论】:

  • 您可能想使用正则表达式来匹配这样的字符串。
  • 我同意正则表达式是一个不错的选择。但是,我觉得我需要先掌握 C++ 的基础知识。有没有办法用简单的语法来做到这一点?使用类似于我可能拥有的东西?
  • 如果要允许带小数的数字,则必须将小数点添加到convert 变量并使用atof(或std::stod)转换为双精度数。如果它不起作用,请使用调试器查看执行失败的地方。

标签: c++ validation input


【解决方案1】:

编写解析代码很棘手。解析时,很容易把控制流弄得一团糟。我建议将 I/O 与验证代码分开:创建一个单独的函数 bool IsVaildInt(const std::string&amp; s),返回 s 是否为有效输入,并在调用函数中执行提示。

有助于系统地思考每个字符的有效输入内容。如果您像 cigien 建议的那样熟悉正则表达式,那么即使您最终手动编写解析代码而不是使用正则表达式库,这也可能是组织方法的好方法。

以下是您发布的要求:

* The first character can be a number, +, -, or a decimal point
* All other characters can be numeric, a comma or a decimal point
* Any commas must be in their proper location (ie, separating hundreds
  from thousands, from millions, etc)
* No commas after the decimal point
* Only one decimal point in the number

这是很多逻辑,但它是可行的。听起来您正在将其作为掌握 C++ 基础知识的练习,所以我不会发布任何代码。相反,这是我将如何处理此问题的大纲:

  1. 测试第一个字符是否为 0-9、+、- 或小数点。如果不是,则返回无效。

  2. 搜索字符串是否有小数点。如果是,请记住它的位置。

  3. 从最后一个字符开始循环遍历剩余的字符。

    • 与循环索引分开,制作一个计数器,说明当前数字的位置(... -1 表示十分位,0 表示个位,1 表示十位,2 表示百位,...)。如果字符串有小数点,则使用它与字符串长度来确定最后一个字符的位数。

    • 如果字符是逗号,请检查它与当前数字位置相比是否位于有效位置。如果不是,则返回无效。

    • 否则,如果字符是小数点,它必须是前面标识的那个。如果不是,则表示有多个小数点,所以返回无效。

    • 否则,字符必须是数字 0-9,并且数字位置计数器应该递增。如果字符不是数字,则返回无效。

  4. 最后,如果循环一直通过而没有遇到错误,则返回该字符串是有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2012-11-02
    • 1970-01-01
    • 2014-10-29
    相关资源
    最近更新 更多