Почему разница в поведении флага EOF IOStream при извлечении из `char` против` int`? - PullRequest
1 голос
/ 05 ноября 2011

Недавно я столкнулся с ошибкой в ​​моем программном обеспечении, которая была вызвана объектом stringstream, для которого был установлен флаг EOF, прежде чем я ожидал этого. Хотя мне удалось выяснить, что произошло, я не смог выяснить, почему это происходит. Пример:

stringstream test ("a b");
char temp, temp2;

test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;  

При запуске это показывает:

eof: 0

Это результат, который я ожидаю. (Я ожидаю, что поток строк установит флаг EOF в 1, когда я попытаюсь что-то прочитать снова)

Однако, когда я внесу небольшое изменение в приведенный выше пример:

stringstream test ("4 2");
int temp, temp2;

test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;

вывод показывает:

eof: 1

Почему флаг EOF устанавливается в этой ситуации, а не в предыдущей?

Ответы [ 2 ]

8 голосов
/ 05 ноября 2011

Когда вы извлекаете один символ за раз, поток не может знать, что EOF достигнут, пока вы не попытаетесь извлечь символ, которого там нет.

Но когда вы извлекаете отформатированные данные в тип, подобный int, анализатор пытается извлечь столько символов из потока, сколько он может , чтобы сформировать число;часть «пытается извлечь символ, которого там нет» будет происходить как часть этого процесса (фактически, последняя «итерация»), поэтому можно установить EOF.

2 голосов
/ 05 ноября 2011

operator>> пропускает пробельные символы по умолчанию, поэтому при первом чтении в символ будет читаться a, при втором пропускается и читается b, при третьем будет достигнут конец строки и произойдет ошибка установка флага eof.

В случае int при синтаксическом анализе int можно прочитать несколько символов, поскольку int может быть представлен несколькими цифрами. Во время чтения целого числа будет предпринята вторая попытка чтения после чтения 2. Это установит флаг eof для потока, хотя чтение int будет успешным.

Именно поэтому вы должны проверить !fail(), а не good(), чтобы увидеть, была ли успешной операция чтения, и почему преобразование потока в bool (или void* в C ++ 03) также использует !fail().

...