整数输入验证 - 拒绝非整数输入并在C ++中请求另一个输入?

时间:2015-04-15 11:33:14

标签: c++ validation input int

当valid_office_num为false时,此函数在while循环内的另一个函数中被调用。问题是如果输入以数字开头但后跟其他无效字符(例如5t),则它取数字部分并接受它作为有效输入。我希望它考虑整个输入并拒绝它,以便它可以要求另一个。我以为我可以使用getline()但我不能使用cin.fail()。我怎么能实现这种行为?

我忘了提到我是C ++的新手,到目前为止我只学过基础知识。

(要明确所需的行为是拒绝包含除数字之外的任何内容。这不是整数范围检查问题。如果它不是整数,则丢弃它并请求另一个整数)

//Function to read a valid office number, entered by user
int read_office_num()
{
    //Declaration of a local variable
    int office_num;

    //Read input
    cin >> office_num;

    //Check if input was valid
    if (cin.fail())
    {
        //Print error message
        cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
        //Clear error flags
        cin.clear();
        //Ignore any whitespace left on input stream by cin
        cin.ignore(256, '\n');
    }
    else
    {
        //Office number entered is valid
        valid_office_num = true;
    }

    return office_num;
}

6 个答案:

答案 0 :(得分:2)

从我收集到的内容,您希望将整行读取为数字,否则会失败?

好吧,你可以使用std::getline(),但你必须遵循以下算法(我将把实现留给你......)

  1. 使用std::getline(cin, str)读取一行,如果返回true,则
  2. 使用std::stoi(str, &pos)转换为整数并获取最后一个整数的位置
  3. 如果pos != str.size()那么整行不是整数(或者如果上面抛出异常),则它不是有效整数,否则返回值...

答案 1 :(得分:1)

您可以使用stringstream

int read_office_num()
{
    //Declaration of a local variable
    int office_num;

    string input = "";

    while (true) {
        getline(cin, input);
        stringstream myStream(input);
        if (myStream >> office_num)
            break;
        cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
    }

    return office_num;
}

如果你想拒绝像123 xxx这样的输入,你可以添加一个额外的检查来验证收到的字符串是否确实是一个整数:

bool is_number(const string& s)
{
    string::const_iterator itr = s.begin();
    while (itr != s.end() && isdigit(*itr)) ++itr;
    return !s.empty() && itr == s.end();
}

int read_office_num()
{
    //Declaration of a local variable
    int office_num;

    string input = "";

    while (true) {
        getline(cin, input);
        stringstream myStream(input);
        if (is_number(input) && myStream >> office_num)
            break;
        cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
    }

    return office_num;
}

答案 2 :(得分:1)

使用std::string作为std::getline()读取一行输入。

检查字符串并检查它是否包含任何非数字字符。

如果字符串只包含数字,请使用std::istringstream从字符串中读取整数。否则报告失败,或采取任何其他需要的恢复操作(例如,丢弃整个字符串并返回读另一个字符串)。

答案 3 :(得分:1)

您应该只查看cin中剩余的输入字符数。您可以使用in_avail

执行此操作

你的功能可能最终会有这样的身体:

//Declaration of a local variable
int office_num;

//Read input and check if input was valid
for (cin >> office_num; cin.rdbuf()->in_avail() > 1; cin >> office_num){
    //Print error message
    cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
    //Ignore any whitespace left on input stream by cin
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

//Office number entered is valid
valid_office_num = true;

return office_num;

兴趣点:

  1. cin中至少有一个字符,否则cin会被标记为bad而且不会很好
  2. 如果valid_office_num以这种方式实施,则您不需要read_office_num,因为valid_office_num在返回之前始终会设置为true

答案 4 :(得分:0)

嗯。我可能会遗漏一些东西,但为什么不读一行,修剪它,使用正则表达式验证一个数字然后利用strstream的设施或只是atoi如果你必须?在所有现实中,我可能只是让用户逃脱无关的输入(但如果我确定我总是以交互方式运行,则丢弃它)。遵循座右铭&#34;宽容你所接受的。&#34;

&#34;互动&#34;告诫很重要。人们通常不会认为cin是终端。有人可能会变得自大,让你的程序在文本文件或管道中运行,然后它会失败。一种强大的方法可以将数据处理(便携式)与输入方式分开(可能是特定于机器的,因此通过控制台也比stdin / stdout更强大,更有用)。

答案 5 :(得分:0)

以下是使用Boost Lexical Cast

的方法
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>
#include <string>

int read_office_num()
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;
    using namespace std;

    int office_num;
    while (true)
    {
        try
        {
            string input = cin.getline();
            office_num = lexical_cast<int>(*argv));
            break;
        }
        catch(const& bad_lexical_cast)
        {
            cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
        }
    }

    return office_num;
}