1

我编写了这段代码,允许用户选择输入值 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”之外的任何东西都不应被视为有效输入,因此会重复循环。发生的事情是“1asdasd”或“2aods”被认为是有效输入,但我希望它失败。

4

6 回答 6

3

下面是一种基于我在 Stroustrup 的《编程:使用 C++ 的原理和实践》的早期章节中阅读的内容以及Duoas 在 cplusplus.com 上提供的答案的方法。它定义了一个函数 ,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;
    }
}
于 2014-02-05T14:31:21.513 回答
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(当然您必须防止其他数字被接受)。

于 2013-03-17T23:18:56.530 回答
0

这是因为gametype是一个整数,所以它试图读取对整数有效的尽可能多的内容。1asdaosd不是一个有效的整数,所以它停在1. 例如,如果您想完整地阅读该内容,则必须创建gametype一个字符串,但是您将无法像以前那样将其与整数进行比较。

如果需要,您可以将其作为字符串读取,并且如果您想同时处理字符串和整数的情况,那么您可以使用类似stoi尝试将字符串转换为整数的方法。然后捕获std::invalid_argument异常,以便您可以知道字符串是否可以转换为整数。如果不能,那么您知道将其保留为字符串。

于 2013-03-17T23:12:17.180 回答
0

只要输入可以这样解释,它就会读取一个 int 。然后停止。如果你读入一个字符串变量,它会得到它。

于 2013-03-17T23:13:04.340 回答
0
  1. 将数据读入字符串变量。
  2. 检查数据是否为有效整数。
  3. 将字符串转换为整数。

乏味,但这是唯一的方法

于 2013-03-17T23:16:01.160 回答
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);
于 2013-03-18T01:03:28.047 回答