У меня есть следующая программа, написанная на C ++:
Проблема этой программы в том, что если пользователь вводит отрицательное число, оно НЕ перехватывается строкой. if(!cin)
, Я думал, что целые числа без знака не могут принимать отрицательные числа. Тогда почему, если я введу отрицательное число в размер, оно НЕ будет поймано if(!cin)
и программа продолжает выполнение без сообщений об ошибках?
Я не могу использовать if(size < 0)
, Я хочу показать, как целые числа без знака могут решить проблему отрицательного ввода.
Разница между целыми числами без знака и со знаком на большинстве платформ является знаковым-битом … кроме того, фактическое двоичное значение одинаково, оно просто интерпретируется двумя различными способами в зависимости от знака типа, который представляет двоичное значение , Таким образом, вы можете определенно «представить» вход отрицательного значения как значение без знака … оно не будет интерпретироваться как это значение, но оно может быть определенно введено как это значение без ошибки, установленной в потоке.
Не гуру C ++ или что-нибудь, но вы пытались использовать cin.fail()
вместо! cin и очистите свой буфер с помощью cin.clear()
более глубокое объяснение
C и C ++ позволяют назначать отрицательное значение для объекта без знака. В результате исходное значение уменьшается по модулю 2^n
, где n
размер беззнакового типа. Так, например, unsigned i = -1;
инициализирует i
в UINT_MAX
,
Чек if(!cin)
будет только указывать, что ничего такого был прочитан, как конец файла.
unsigned
целое число не сила вклад должен быть положительным; это просто означает, что значение всегда будет интерпретированы как положительный (см. бит знака), что может иметь драматические последствия, если число фактически отрицательное.
Лучше всего, вероятно, ввести целое число со знаком и затем проверить в коде, является ли оно положительным.
Если вы хотите запретить пользователю вводить отрицательные числа, примите ввод как число со знаком и убедитесь, что он равен или больше нуля.
Стандарт в основном говорит, что когда вы пытаетесь присвоить число целочисленному типу, который находится за пределами диапазона типа, кратные значения типа будут добавляться или вычитаться до тех пор, пока значение не окажется в пределах диапазона.
Так уж получилось, что со значениями, выраженными как 2-е дополнение и в пределах диапазонов целых чисел со знаком и без знака, это означает, что точно такой же битовый шаблон будет назначен любому значению. Отрицательный имеет битовый паттерн из всех, который переводится в максимально возможное значение для беззнакового целого и эквивалентен -1 + 232
или исходное значение плюс величина без знака int.
Или вы можете просто использовать больший тип со знаком со знаком.
long long n = -1;
cout << "Enter a number: ";
cin >> n;
if( !cin.good() )
cout << "Not a valid number." << endl;
else if( n > UINT_MAX )
cout << "Overflow, value is more than UINT_MAX." << endl;
else if( n < 0 )
cout << "Negative, value is less than 0." << endl;
else {
unsigned int m = (unsigned int)n;
cout << "Valid unsigned int was input: " << m << "." << endl;
}