0

我试图确保用户输入是一个正整数,并且无论用户尝试输入什么,我的函数都能正常工作。

int getNumber()
{
    string userInput;
    int userNumber;
    bool badInput = true;
    cout<<"Enter a positive integer: ";
    cin>>userInput;
    while (badInput)
    {
        for (int i=0; i<userInput.length(); i++)
        {
            if (isdigit(userInput[i]))
            {
                badInput = false;
            }
            else
            {
                badInput = true;
                cout<<"That wasn't a valid input, try again: ";
                cin>>userInput;
                break;
            }
        }
    }
    userNumber = atoi(userInput.c_str());
    return userNumber;
}

有没有更清洁的方法来做到这一点,或者这是最好的方法?我尝试了各种其他方法,例如使用 cin.bad 等,但他们总是设法错过一些问题。

4

4 回答 4

1

如果您需要检查正整数,您可能还需要将文本转换为整数。你应该同时做这两个;类似于:

std::string line;
if ( !std::getline( std::cin, line ) ) {
    //  no input available...
} else {
    std::istringstream parser( line );
    int userNumber;
    if ( parser >> userNumber >> std::ws
            && parser.get() == EOF
            && userNumber > 0 ) {
        //  All OK...
    } else {
        //  Some error in the input.
    }
}

strtol如果您有来自其他地方的字符串,也可以使用。错误检测有点棘手,因为strtol 在某些情况下有一些奇怪的语义:

int
getPositiveInteger( std::string const& input )
{
    char const* end;
    errno = 0;
    long results = strtol( input.c_str(), &end, 10 );
    if ( end != input.c_str() ) {
        while ( isspace( static_cast<unsigned char>( *end) ) ) {
            ++ end;
        }
    }
    return (errno == 0
            && end != input.c_str()
            && *end == '\0'
            && results > 0
            && results <= INT_MAX)
        ? results
        : -1;
}

(如果出现错误,我已返回 -1。)

您会注意到必须测试的条件数量,以确保其stdtol正常工作。

于 2013-02-21T10:47:27.610 回答
0

您可以std::string::find_first_not_of()用于测试数字和std::stoi溢出

std::string input;
bool badInput;
int i;

std::cout << "Enter a positive integer: ";
do {
    std::cin >> input;
    try {
        badInput = input.find_first_not_of("0123456789") != std::string::npos;
        if (!badInput)
            i = std::stoi(input);
    } catch (const std::invalid_argument&) {
        badInput = true;
    } catch (const std::out_of_range&) {
        badInput = true;
    }

    if (badInput)
        std::cout << "That wasn't a valid input, try again: ";
} while (badInput);

不过,这不会检查前导+

于 2013-02-21T10:07:16.050 回答
0

你可以简单地使用strtol,像这样:

char str[] = "+12345";
char* end;
long number = strtol(str, &end, 10);
if (number < 0) {
    printf("Number is negative!\n");
    // ...
}
if (*end) {
    printf("Junk found after number: '%s'\n", end);
    // ...
}
于 2013-02-21T10:02:44.297 回答
0

就像mvp说的,strol是要走的路。

bool string_to_int(char* s, int* val) {
   char* endptr;
   errno = 0; /* reset errno */
   int i = strtol(s, &endptr, 10);
   if (endptr == s) return false; /* conversion failed */
   if (*endptr) return false; /* unexpected characters behind the integer */
   if (errno) return false; /* out of range */
   *val = i;
   return true;
}
于 2013-02-21T10:11:02.493 回答