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

あなたは単に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

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

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 に答える