简体   繁体   中英

C++ - Sanitize Integer Whole Number Input

I currently am using a function I found in another StackOverflow post(I can't find it), that I am using before, named "GetInt". My issue with it is that if the user inputs something like "2 2 2" it puts it into my next two Cin's. I have tried getLine, but it requires a string and I am looking for an int value. How would I structure a check to sanitize for an integer value greater than 2 and throw an error to the 2 2 2 answer.

#include <iostream>
#include <string>
#include <sstream>
#include "Board.cpp"
#include "Player.cpp"

using namespace std;

int getInt()
{
int x = 0;
while (!( cin >> x))
{
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    cout << "Please input a proper 'whole' number: " << endl;
}
return (x);
}

and my call

do
{
    //do
    //{
        cout << "How many players are there? \n";
        numberOfPlayers = getInt();
    //} while (isdigit(numberOfPlayers) == false);
} while (numberOfPlayers < 2);

EDIT:

I chose Justin's answer because it was the closest to my original code and solved the issue without major changes.

Integers are delimited by spaces and the input 2 2 2 is just multiple integers. If you want to make sure that just one integer is entered per line you could skip whitespace characters until a newline is found. If a non-whitespace is found prior to a newline you could issue an error:

numberOfPlayers = getInt();
int c;
while (std::isspace(c = std::cin.peek()) && c != '\n') {
    std::cin.ignore();
}
if (c != std::char_traits<char>::eof() && c != '\n') {
    // deal with additional input on the same line here
}

You were on the right track with std::getline . You read the whole line as a string, then put it into a std::istringstream and read the integer out.

std::string line;
if( std::getline(cin, line) ) {
    std::istringstream iss(line);
    int x;
    if( iss >> x ) return x;
}
// Error

This will have the effect of discarding any fluff that comes after the integer. It will only error if there is no input or no integer could be read.

If you want to have an error when stuff appears after the integer, you could take advantage of the way strings are read from a stream. Any whitespace is okay, but anything else is an error:

    std::istringstream iss(line);
    int x;
    if( iss >> x ) {
        std::string fluff;
        if( iss >> fluff ) {
            // Error
        } else {
            return x;
        }
    }

Change your code to this:

int getInt()
{
    int x = 0;
    while (!( cin >> x))
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        cout << "Please input a proper 'whole' number: " << endl;
     }

     cin.clear();
     cin.ignore(numeric_limits<streamsize>::max(), '\n');
     return (x);
 }

Your code to ignore the rest of the line after receiving the integer is only called if the integer collection fails (for example, you type "h" as the number of players).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM