мы читаем конец файла, цикл
inOut.get( ch );
мы читаем конец файла, цикл while завершается и выводится значение 0.
Хотя мы допустили серьезную ошибку, исправить ее совсем несложно, поскольку причина понятна. Надо лишь перед чтением переустановить файл на начало. Это делается с помощью обращения:
inOut.seekg( 0 );
Запустим программу заново. На этот раз она печатает:
Call me Ishmael. Some years ago, never mind
[ 45 ]
Как видим, выводится лишь первая строка текста и счетчик для нее, а оставшиеся шесть строк проигнорированы. Ну что ж, исправление ошибок – неотъемлемая часть профессии программиста. А проблема опять в том, что файл открыт в режиме дозаписи. Как только мы в первый раз вывели cnt, файл оказался позиционирован на конец. При следующем обращении к get() читается конец файла, и цикл while снова завершается преждевременно.
Нам необходимо встать на ту позицию в файле, где мы были перед выводом cnt. Для этого понадобятся еще две инструкции:
// запомнить текущую позицию
ios_base::pos_type mark = inOut.tellg();
inOut << cnt << sp;
inOut.seekg( mark ); // восстановить позицию
После повторной компиляции программа выводит на экран ожидаемый результат. Но посмотрев на выходной файл, мы обнаружим, что она все еще не вполне правильна: окончательное значение счетчика есть на экране, но не в файле. Оператор вывода, следующий за циклом while, не был выполнен.
Дело в том, что inOut находится в состоянии “конец файла”, в котором операции ввода и вывода не
выполняются. Для решения проблемы необходимо сбросить это состояние с помощью функции-члена clear():
inOut.clear(); // обнулить флаги состояния
Окончательный вариант программы выглядит так:
#include <iostream>
#include <fstream>
int main()
{
fstream inOut( "copy.out", ios_base::in|ios_base::app );
int cnt=0;
char ch;
inOut.seekg(0);
while ( inOut.get( ch ))
{
cout.put( ch );
cnt++;
if ( ch == '\n' )
{
Содержание Назад Вперед