Я думаю, что ваш вопрос: «Почему я получаю еще одну строку, чем есть в файле?»
Представьте себе файл:
line 1
line 2
line 3
Файл может быть представлен в ASCII следующим образом:
line 1\nline 2\nline 3\n
(где \n
- байт 0x10
.)
Теперь давайте посмотрим, что происходит до и после каждого getline
вызова:
Before 1: line 1\nline 2\nline 3\n
Stream: ^
After 1: line 1\nline 2\nline 3\n
Stream: ^
Before 2: line 1\nline 2\nline 3\n
Stream: ^
After 2: line 1\nline 2\nline 3\n
Stream: ^
Before 2: line 1\nline 2\nline 3\n
Stream: ^
After 2: line 1\nline 2\nline 3\n
Stream: ^
Теперь вы думаете, что поток пометит eof
, чтобы указать конец файла, верно? Нету! Это связано с тем, что getline
устанавливает eof
, если маркер конца файла достигнут "во время работы" . Поскольку getline
завершается, когда достигает \n
, маркер конца файла не читается, а eof
не помечается. Таким образом, myfile.eof()
возвращает false, и цикл проходит еще одну итерацию:
Before 3: line 1\nline 2\nline 3\n
Stream: ^
After 3: line 1\nline 2\nline 3\n
Stream: ^ EOF
Как вы это исправите? Вместо проверки eof()
, посмотрите, вернет ли .peek()
EOF
:
while(myfile.peek() != EOF){
getline ...
Вы также можете проверить возвращаемое значение getline
(неявное приведение к bool):
while(getline(myfile,line)){
cout<< ...