首页 > 解决方案 > 判断用户输入的类型时的问题

问题描述

在判断用户输入的号码类型是否正确时遇到了一些问题。

我想设计一个只适用于输入int型号的程序。当用户输入另一种类型(如, double, chartype)时,系统会输出错误。但是,当用户输入非法类型的值时,系统首先输出一个输入指令,然后输出错误语句。

这部分的代码如下:

for (int i = 0; i < nStudents; ++i) {
    std::cout << "Please input the score of Student " << (i + 1) << ": ";
    std::cin >> nArray[i];
    if (!std::cin.good()) {
      std::cout << std::endl <<  "The data type is not applicable. Please input integers!" << std::endl;
      return 0;
    }
}

当我输入一个非法值时,结果是:

Please input the number of the students: 3
Please input the score of Student 1: 1.2
Please input the score of Student 2: 
The data type is not applicable. Please input integers!

你能给我一个解决方案吗?谢谢!

标签: c++

解决方案


为此使用整数流运算符过于简单。如果输入因任何原因失败,则必须重置错误状态,忽略某些字符并继续阅读。

更重要的是,如果遇到像小数点这样的东西,只要在它之前出现看起来像整数的东西就可以了。当然,下一次调用将失败,因为您尝试读取一个整数,但流中的下一个字符是'.'.

这就是您的情况,您甚至没有尝试从错误中恢复。

通常,当您请求用户输入时,用户应该在输入值后按 Enter。因此,您可以为此使用基于行的输入。为此,您使用std::stringwith std::getline。一旦您将一行输入作为字符串,您就可以轻松地从该字符串中解析所需的值。

这是一个简单的程序,用于std::stoi将输入行转换为整数。但是,由于“1.2”仍将正确解析为整数值 1,因此添加了一些附加逻辑,仅允许任何剩余字符使用空格。

#include <cctype>
#include <iostream>
#include <stdexcept>
#include <string>

int main()
{
    std::string line;
    while (std::getline(std::cin, line))
    {
        try {
            size_t pos = 0;
            int ival = std::stoi(line, &pos);
            while (pos < line.size()) {
                if (!std::isspace(line[pos]))
                    throw std::runtime_error("Malformed integer value");
                ++pos;
            } 
            std::cout << "Integer read: " << ival << '\n';
        }
        catch(std::exception &e)
        {
            std::cerr << "Invalid input: " << line << '\n';
        }
    }
}

现场演示:https ://godbolt.org/z/vK1WxTh3n


推荐阅读