Чтение «unsigned int» с использованием «cin» - PullRequest
6 голосов
/ 06 марта 2012

Я пытаюсь прочитать unsigned int, используя cin следующим образом:

#include <limits.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    unsigned int number;

    // UINT_MAX = 4294967295
    cout << "Please enter a number between 0 and " << UINT_MAX << ":" << endl;

    cin >> number;

    // Check if the number is a valid unsigned integer
    if ((number < 0) || ((unsigned int)number > UINT_MAX))
    {
        cout << "Invalid number." << endl;
        return -1;
    }
    return 0;
}

Однако всякий раз, когда я ввожу значение, превышающее верхний предел целого числа без знака (UINT_MAX),Программа отображает 3435973836.Как проверить, находится ли введенный пользователем ввод от 0 до UINT_MAX?

Ответы [ 5 ]

5 голосов
/ 06 марта 2012

Две вещи:

  • Проверка, является ли целое число без знака <0 или> UINT_MAX, бессмысленно, поскольку оно никогда не сможет достичь этого значения! Ваш компилятор, вероятно, уже жалуется с предупреждением типа «сравнение всегда ложно из-за ограниченного диапазона типов».

  • Единственное решение, которое я могу придумать, это перехватить ввод в строке, а затем использовать старомодный strtoul (), который устанавливает errno в случае переполнения.

т.е:.

#include <stdlib.h>

unsigned long number;
std::string numbuf;
cin >> numbuf;
number = strtoul(numbuf.c_str(), 0, 10);
if (ULONG_MAX == number && ERANGE == errno)
{
    std::cerr << "Number too big!" << std::endl;
}

Примечание: strtoul возвращает unsigned long; нет функции strtou (), возвращающей беззнаковое целое.

3 голосов
/ 06 марта 2012

Ваша проверка не имеет смысла (что вам скажет компилятор с правильно активированными предупреждениями), поскольку ваше значение никогда не меньше 0 и никогда не превышает UINT_MAX, поскольку это наименьшее и наибольшее значение переменной типа unsigned int (котораячисло есть) может содержать.

Используйте состояние потока, чтобы определить, правильно ли работает чтение в целое число.

2 голосов
/ 06 марта 2012

Когда пользователи вводят число больше UINT_MAX, cin caps оно равно UINT_MAX в любом случае.Значение также не может быть отрицательным.

Если вам нужно расширить диапазон, используйте unsigned long long для ввода и приведите к unsigned int после проверки.Это не защитит от чисел, которые находятся за пределами диапазона unsigned long long.

Для решения общего назначения вы можете прочитать string и выполнить преобразование самостоятельно, используя unsigned long long в качестверезультат.

2 голосов
/ 06 марта 2012

Вы можете прочитать длинную строку без знака и проверить ее на соответствие целому пределу без знака.

1 голос
/ 06 марта 2012

Если вы попытаетесь прочитать его в unsigned int, вам придется ограничиться ограничениями unsigned int.

Самый общий способ сделать то, что вы просите, - прочитать входные данные как string и проанализировать их, чтобы убедиться, что они находятся в нужном диапазоне. После того, как вы проверили его, вы можете преобразовать его в unsigned int.

...