首页 > 解决方案 > C++ 数字输入验证

问题描述

我习惯了 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++validationinput

解决方案


编写解析代码很棘手。解析时,很容易把控制流弄得一团糟。我建议将 I/O 与验证代码分开:创建一个单独的函数bool IsVaildInt(const std::string& 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. 最后,如果循环一直执行而没有遇到错误,则返回该字符串是有效的。


推荐阅读