C ++ cin只接受数值

时间:2013-03-17 23:09:26

标签: c++ validation

我编写了这段代码,允许用户选择输入值1或2.除了一个小问题外,这个工作完全正常:

如果用户输入类似“1asdaosd”的内容,则输入仅被识别为1。

我已经尝试过使用isdigit功能,但我仍然无法完成这项工作。

bool validInput;
    do
    {
        cout << "Choose the game type: ";
        cin >> gametype;
        validInput = true;
        if (cin.fail())
        {
            validInput = false;
            cin.clear();
            cin.ignore(std::numeric_limits<int>::max(), '\n');
        }
        if (gametype<1 || gametype>2) {
            validInput = false;
        }
    } while (!validInput);

预期的行为应该是:

“1”或“2”以外的任何内容都不应被视为validInput,因此重复该循环。会发生什么是“1asdasd”或“2aods”被认为是validInput但我希望它失败。

6 个答案:

答案 0 :(得分:3)

下面是一个基于我在Stroustrup的编程:使用C ++的原理和实践的早期章节和cplusplus.com上由Duoas提供的answer的内容中阅读的内容的方法。它定义了一个函数get_int_between(),允许你做这样的事情:

int my_variable;
get_int_between(my_variable, min, max, prompt, error_msg);

会提示,验证并存储到my_variable中。

为了好玩,我还添加了一个函数get_int(my_variable, prompt, error_msg),它可以执行相同的操作,但允许任意值的整数。

#include <iostream>
#include <sstream> // stringstream

void get_int(int& d, std::string prompt, std::string fail);

void get_int_between(int& d, int min, int max, std::string prompt, std::string fail);

int main()
{
    int my_number = 1; // initialize my_number

    get_int(my_number, "Please enter an integer: ", "Sorry, that's not an integer.\n"); 
    //Do something, e.g. 
    std::cout << "You entered: " << my_number << "\n";

    get_int_between(my_number, 1, 2, "Choose the game type (1 or 2): ", "Sorry, that's not an integer.\n");
    //Do something, e.g.:
    std::cout << "Let's play Game " << my_number << "!\n";

    return 0;
}

void get_int(int& d, std::string prompt, std::string fail)
{
    while(1) {

        std::cout << prompt;
        std::string str;
        std::cin >> str;

        std::istringstream ss(str);
        int val1;
        ss >> val1;

        if(!ss.eof()) {
            std::cout << fail;
            continue;
        } else {
            d = val1;
            break;
        }
    }
}

void get_int_between(int& d, int min, int max, std::string prompt, std::string fail)
{
    while(1) {
        get_int(d, prompt, fail);
        if(d > max || d < min) {
            std::cout << "Sorry, your choice is out of range.\n";
            continue;
        }
        break;
    }
}

答案 1 :(得分:1)

如果您想使用字符串,请使用getline

#include <iostream>     // std::cin, std::cout
int main () 
{
char name[256], title[256];

std::cout << "Please, enter your name: ";
std::cin.getline (name,256);

std::cout << "Please, enter your favourite movie: ";
std::cin.getline (title,256);

std::cout << name << "'s favourite movie is " << title;

return 0;
}

如果您将游戏类型设为 int ,它只接受1或2(当然您必须阻止其他数字被接受)。

答案 2 :(得分:0)

这是因为gametype是一个整数,所以它试图读取尽可能多的整数。 1asdaosd不是有效整数,因此它会在1处停止。如果你想完全阅读那个东西,你必须让gametype成为一个字符串,但是你将无法像现在这样将它与整数进行比较。

如果需要,可以将其作为字符串读取,如果要处理字符串和整数的情况,则可以使用类似stoi的内容来尝试将字符串转换为整数。然后捕获std::invalid_argument异常,以便您可以知道字符串是否可以转换为整数。如果它不能,那么你知道将它保持为字符串。

答案 3 :(得分:0)

它读取一个int,输入可以解释为这样。然后停下来。如果你读入一个字符串变量,它将全部收到。

答案 4 :(得分:0)

  1. 将数据读入字符串变量。
  2. 检查数据是否为有效整数。
  3. 将字符串转换为整数。
  4. 乏味,但这是唯一的方法

答案 5 :(得分:0)

我猜你想在每一行都有一个输入值。您需要将其作为字符串读取,然后检查您是否获得了比您要求的更多。如果您需要它作为整数,您可以稍后转换读取字符串。

我还假设你只需要读取单个数字的整数。更多的数字需要循环中的字符串到整数转换以及更多的检查。

string gametype;
do
{
    cout << "Choose the game type: ";
    // read one word as string, no conversion, so will not fail (may hit eof though)
    cin >> gametype;
    // ignore rest of line (assuming you want next valid input on next line)
    cin.ignore(std::numeric_limits<int>::max(), '\n');
}
while ( gametype.size() != 1 || gametype.at(0) < '1' || gametype.at(0) > '2') );

// char to int conversion (single digit only)
int gametypeint = gametype.at(0) - '0';

// other way to convert string to int
istringstream iss(gametype);
iss >> gametypeint;

// yet another way (C++11)
gametypeint = stio(gametype);