2010-10-19 2 views
3

Не предлагает ли C++ гарантия сохранения целостности переменных при сбое ввода? С более старыми версиями gcc такая программа сохраняет значение i при ошибке i (например, если вместо ввода на вводе введена буква). С Ubuntu 10.10 (gcc 4.4.5) i сбрасывается до нуля в случае сбоя ввода.Должен ли C++ сохранять переменные неизменными при сбое ввода?

#include <iostream> 

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

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

Спасибо.

+1

Да, мы знаем, что мы делаем ;-) Смотрите https: //gcc.gnu.org/bugzilla/show_bug.cgi? id = 57213 –

ответ

5

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

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


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

От C++ 03:

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

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

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

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

Да, спасибо. Мой главный вопрос заключается в том, определяет ли стандарт C++ это поведение и где? –

+0

@ Rémi Я понимаю. Я отредактировал свой ответ – KeatsPeeks

+0

Спасибо, это отвечает на мой вопрос. –

1

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

Вы можете проанализировать строку во временное использование istringstream.

3

Стандарт 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 хранилось в случае ошибки преобразования.