Joshua Nixon
Joshua Nixon

Reputation: 1427

Get only integers as input, code not working as expected

I am trying to allow only integrers to be inputted

Should Reject:

Should Accept:

Current Code

int getIntInput() {
    int userInput;

    while (true) {
        std::cout << "> ";
        std::cin >> userInput;
        std::cout << std::flush;

        if (std::cin.fail()) {
            std::string cinBuffer;
            std::cin.clear();
            std::getline(std::cin, cinBuffer);
            continue;
        }
        break;
    }
    return userInput;
}

Updated Code

Issues:

Finished Code

Upvotes: 2

Views: 154

Answers (3)

Marek R
Marek R

Reputation: 37607

template<class T>
T findInStreamLineWith(std::istream &input) {
    std::string line;
    while (std::getline(input, line)) {
        std::istringstream stream(line);
        T x;
        if (stream >> x >> std::ws && stream.eof()) {
            return x;
        }
        // reenter value
        // cout << "Enter value again: ";
    }
    throw std::invalid_argument("can't find value in stream");
}

…
auto x = findInStreamLineWith<int>(std::cin);

Upvotes: 0

user9950573
user9950573

Reputation: 41

If you don't mind the overhead, I would grab the input from cin with cin.getline() and save it into a string. Then loop through the string and call isdigit on each char. You can discard the chars that aren't digits by useing the str.erase function.

You will need to #include cctype for isdigit().

Note: this will have at least O(N) runtime based on the length of your string.

Upvotes: 2

DGounaris
DGounaris

Reputation: 182

The way cin works when having to read an int, is that it starts parsing the integer and stops when it finds a non-int character, storing the parsed int in the variable. That's why on float numbers it stops on the dot and in input '5g' it will stop on g.

What you can do instead if you only want integer input, is to read the whole line and then check if every character in your string is numeric, with the following piece of code:

bool onlyNums = true;
for (int i=0;i<rawInput.size();i++) {
    if (!isdigit(rawInput[i]))
        onlyNums = false;
}

if (!onlyNums)
    continue;

(You have to include ctype.h library for the above code)

Upvotes: 2

Related Questions