С++ для начинающих



Файловый ввод/вывод - часть 7


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' )

        {




Содержание  Назад  Вперед