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




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


abcd

efg

hi

j

Программа должна создать файл, модифицированный следующим образом:

abcd

efg

hi

j

5 9 12 14 24

Так выглядит первая попытка реализации:

#include <iostream>

#include <fstream>

main() {

    // открыть файл для ввода и дозаписи

    fstream inOut( "copy.out", ios_base::in|ios_base::app );

    int cnt = 0;   // счетчик байтов

    char ch;

    while ( inOut.get( ch ))

    {

        cout.put( ch ); // скопировать на терминал

        ++cnt;

        if ( ch == '\n' ) {

            inOut << cnt ;

            inOut.put( ' ' ); // пробел

        }

    }

    // вывести окончательное значение счетчика байтов

    inOut << cnt << endl;

    cout << "[ " << cnt << " ]" << endl;

    return 0;

}

inOut – это объект класса fstream, связанный с файлом copy.out, открытым для ввода и дозаписи. Если файл открыт в режиме дозаписи, то все новые данные записываются в конец.

При чтении любого (включая пробельные) символа, кроме конца файла, мы увеличиваем переменную cnt на 1 и копируем прочитанный символ на терминал, чтобы вовремя заметить ошибки в работе программы.

Встретив символ новой строки, мы записываем текущее значение cnt в inOut. Как только будет достигнут конец файла, цикл прекращается. Окончательное значение cnt выводится в файл и на экран.

Программа компилируется без ошибок и кажется правильной. Но если подать на вход несколько фраз из романа “Моби Дик” Германа Мелвилла:

Call me Ishmael.  Some years ago, never mind

how long precisely, having little or no money

in my purse, and nothing particular to interest

me on shore, I thought I would sail about a little

and see the watery part of the world.  It is a

way I have of driving off the spleen, and

regulating the circulation.

то получим такой результат:

 [ 0 ]

Программа не вывела ни одного символа, видимо, полагая, что файл пуст. Проблема в том, что файл открыт для дозаписи и потому позиционирован на конец. При выполнении инструкции




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