Почему Integer Overflow вызывает ошибки с C ++ IoStreams?

StackOverflow https://stackoverflow.com/questions/3582509

  •  01-10-2019
  •  | 
  •  

Вопрос

Хорошо, поэтому у меня есть некоторые проблемы с yoStreams C ++, которые чувствуют себя очень странно, но, вероятно, определено поведение, учитывая, что это происходит с помощью MSVC ++, так и G ++.

Скажем, у меня есть эта программа:

#include <iostream>
using namespace std;

int main()
{
   int a;
   cin >> a;
   cout << a << endl;
   cin >> a;
   cout << a << endl;

   return 0;
}

Если я намеренно переполнено, предоставив первый CIN значение, который больше, чем максимальный предел int, все дальше звонки cin.operator>>() немедленно вернется по какой-то причине, а также a установлено на некоторую ценность. Значение, кажется, не определено.

Почему и где это поведение документально? Есть ли способ выяснить, произошел ли такой переполнение?

Кроме того, эта подобная программа, кажется, работает, как я намерен. Если я переполняю значение, это даст a некоторое значение и продолжать, как будто переполнение никогда не произошло.

#include <cstdio>
using namespace std;

int main()
{
   int a;
   scanf("%d", &a);
   printf("%d\n", a);
   scanf("%d", &a);
   printf("%d\n", a);
   scanf("%d", &a);
   printf("%d\n", a);

   return 0;
}
Это было полезно?

Решение

iOStreams предназначен для обнаружения ошибок и ввести состояние ошибки. Вы получаете тот же результат от целочисленного переполнения, как от ввода не цифровой строки.

Бросать cin (или любой поток) к bool или проверка cin.rdstate() определить, произошла ли ошибка.

Вызов cin.clear() а также cin.ignore() вымочить ошибку. Он заберет в точке персонажей, которые не удалось.

Что касается официальной документации, стандарт к сожалению становится немного непостижимым в кишечнике IoStreams. См. §27.6.1.2.1, 27.6.1.2.2 и 22.2.2.1.1 / 11 (не шучу):

- Последовательность символов, накопленных на этапе 2, вызвала бы Scanf сообщать о неисправности входных данных. IOS_BASE :: Failbit назначается ошибкой.

То Документация для ScanF. так же непроницаемо, и я возьму это на веру, что переполнение должно быть ошибкой.

Другие советы

Я бы подумал, что CIN настроен на состояние ошибки из-за неверного чтения.

1-й ответ здесь объясняет это.

http://www.dreamincode.net/forums/topic/93200-cin-checking-and-resetting-gror-state/

Просто попробовал этот код, и это, кажется, настраивается на провал

#include <iostream> 
using namespace std; 

int main() 
{ 
    int a; 
    cin >> a; 
    if(!cin)
    {
        cin.clear();
    }
    cout << a << endl; 
    cin >> a; 
    if(!cin)
    {
        cin.clear();
    }
    cout << a << endl; 

    return 0; 
}

a начинается с неопределенным значением. Это не cinвина. Пытаться:

if (cin >> a) {
  cout << a endl;
}

Это проверит, будет ли чтение в a преуспеть, прежде чем использовать a

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top