Должен ли C ++ сохранять переменные нетронутыми при сбое ввода? - PullRequest
3 голосов
/ 19 октября 2010

Разве C ++ не дает никаких гарантий относительно сохранения переменных в неизменном состоянии при сбое ввода? В более старых версиях gcc такая программа сохраняет значение -1 при неудаче (например, если вместо ввода числа вводится буква). В Ubuntu 10.10 (gcc 4.4.5) i сбрасывается на ноль в случае сбоя входа.

#include <iostream>

int main()
{
 int i = -1;
 std::cin >> i;
 std::cout << "i = " << i << '\n';
 return 0;
}

Такое поведение сильно нарушает мой код. Я полагаю, что gcc люди знают, что они делают, и это, вероятно, будет моей ошибкой. Если кто-нибудь знает стандарт, я хотел бы знать, что он говорит об этой ситуации.

Спасибо.

Ответы [ 3 ]

5 голосов
/ 19 октября 2010

Не полагайтесь на переменную.Положитесь на состояние потока:

if (std::cin >> i) // "if (!std::cin.fail())" would also work
{
    // ok
}
else
{
    // error
}

Что касается того, почему поведение изменилось, то это потому, что стандарт C ++ эволюционировал:

От C ++ 03:

Если возникает ошибка, val не изменяется;в противном случае оно устанавливается равным полученному значению.

Из C ++ 0x (ну .. из последнего черновика, к которому у меня есть доступ):

Числовое значение длябыть сохраненным может быть одним из:

  • ноль, если функция преобразования не преобразует все поле.
  • самое положительное (или отрицательное) представимое значение, если поле, которое нужно преобразовать в целочисленный тип со знаком, представляет слишком большое положительное (или отрицательное) значение, чтобы быть представленным в val.
  • наиболее положительное представимое значение, если поле, подлежащее преобразованию в целочисленный тип без знака, представляет значение, которое не может быть представлено в val.
  • преобразованное значение, в противном случае.
3 голосов
/ 19 октября 2010

Стандарт C ++ изменился в требуемом поведении для этого случая.Требования можно найти в [lib.facet.num.get.virtuals] (22.2.2.1.2 в C ++ 03, 22.4.2.1.2 в C ++ 0x)

в C ++03, требование состоит в том, что старое значение не изменяется в случае ошибки.В C ++ 0x требуется, чтобы значение 0 сохранялось в случае ошибки преобразования.

1 голос
/ 19 октября 2010

Если вы хотите, чтобы неудачный входной поток не влиял на вашу переменную, и вы не хотите, чтобы он переводил поток в сбойное состояние, затем переводите поток в строку, анализируйте строку во временную и, если все это успешно, продолжить.

Вы можете разобрать строку во временную строку с помощью istringstream.

...