Почему целочисленное переполнение вызывает ошибки в C ++ iostreams? - PullRequest
5 голосов
/ 27 августа 2010

Хорошо, у меня есть некоторые проблемы с iostreams 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;
}

Ответы [ 3 ]

7 голосов
/ 27 августа 2010

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, вызвала бы сканирование ксообщить о сбое ввода.ios_base :: failbit назначен на err.

Документация для scanf столь же непроницаема, и я верю, что переполнение должно быть ошибкой.

1 голос
/ 27 августа 2010

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

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

http://www.dreamincode.net/forums/topic/93200-cin-checking-and-resetting-error-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; 
}
0 голосов
/ 27 августа 2010

a начинается с неопределенного значения. Это не ошибка cin. Попробуйте:

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

Перед использованием a

будет проверено, успешно ли выполнено чтение в a.
...