Возможный дубликат:
Почему iostream :: eof внутри условия цикла считается неправильным?
У меня очень простой вопрос …
#include<iostream>
using namespace std;
int main()
{
char x;
while(!cin.eof())
{
cin>>x;
cout<<"char: "<< x << endl;
}
return 0;
}
Почему, когда я пытаюсь запустить этот код в Linux:
./имя файла < test_file.txt
Результат:
символ:
символ: б
символ: с
символ: d
символ: d
только когда test_file.txt:
ABCD
Конец файла обнаружен провал операция ввода.
Итак, в
cin>>x;
cout<<"char: "<< x << endl;
оператор вывода выполняется даже в случае сбоя операции ввода.
И когда это терпит неудачу, это не обновляет x
,
Вместо тестирования .eof()
, тестовое задание .fail()
,
Вы можете сделать это, используя объект потока непосредственно как условие, например,
#include<iostream>
using namespace std;
int main()
{
char x;
while( cin >> x )
{
cout<<"char: "<< x << endl;
}
}
Здесь выражение cin >> x
выполняет операцию ввода, которая может обновить x
и как его результат выражения возвращает ссылку на поток, т.е. cin
, Так cin
используется непосредственно как условие. Это вызывает преобразование в логическое значение, которое определяется так, что оно само по себе эквивалентно !cin.fail()
(то есть выражение cin >> x
как условие эквивалентно написанию !(cin >> x).fail()
или, как выражение запятой, (cin >> x, !cin.fail())
).
Вы используете слегка неверный шаблон для чтения из файла. Правильная форма
while(cin >> x) {
cout<<"char: "<< x << endl;
}
Имейте в виду, что eof
говорит тебе если вы пытались прочитать после конца ввода; это не говорит вам, если вы только собираюсь сделать это. Ваш оригинальный код читает d
в первый раз видит, что он не пытался прочитать с конца, а затем пытается прочитать еще раз. Это чтение не удается, но вы сейчас внутри цикла и x
имеет значение d
из предыдущей итерации, поэтому он печатается еще раз.
Приведенный выше код проверяет состояние потока (который случайно будет не только перехватывать конец файла, но и ошибки) после он попытался прочитать в x
; поэтому цикл не будет выполнен вообще после первого чтения, которое терпит неудачу.
Вы должны использовать для цикла с размером файла, чтобы избежать нулевого символа