Выбрать главу

#include

const int fileCnt = 5;

string fileTabl[ fileCnt ] = {

"Melville", "Joyce", "Musil", "Proust", "Kafka"

};

int main()

{

ifstream inFile; // не связан ни с каким файлом

for ( int ix = 0; ix

бъект класса fstream (производного от iostream) может открывать файл для ввода или вывода. В следующем примере файл word.out сначала считывается, а затем записывается с помощью объекта типа fstream. Созданный ранее в этом разделе файл word.out содержит объект WordCount:

#include fstream

#include "WordCount.h"

int main()

{

WordCount wd;

fstream file;

file.open( "word.out", ios::in );

file wd;

file.close();

cout "Прочитано: " wd endl;

// операция ios_base::out стерла бы текущие данные

file.open( "word.out", ios::app );

file endl wd endl;

file.close();

}

Объект класса fstream может также открывать файл одновременно для ввода и вывода. Например, приведенная инструкция открывает файл word.out для ввода и дозаписи:

fstream io( "word.out", ios_base::in|ios_base::app );

Для задания нескольких режимов используется оператор побитового ИЛИ. Объект класса fstream можно позиционировать с помощью функций-членов seekg() или seekp(). Здесь буква g обозначает позиционирование для чтения (getting) символов (используется с объектом класса ofstream), а p – для записи (putting) символов (используется с объектом класса ifstream). Эти функции делают текущим тот байт в файле, который имеет указанное абсолютное или относительное смещение. У них есть два варианта:

// установить абсолютное смещение в файле

seekg( pos_type current_position )

// смещение от текущей позиции в том или ином направлении

seekg( off_type offset_position, ios_base::seekdir dir );

В первом варианте текущая позиция устанавливается в некоторое абсолютное значение, заданное аргументом current_position, причем значение 0 соответствует началу файла. Например, если файл содержит такую последовательность символов:

abc def ghi jkl

то вызов

io.seekg( 6 );

* позиционирует io на шестой символ, т.е. на f. Второй вариант устанавливает указатель рабочей позиции файла на заданное расстояние от текущей, от начала файла или от его конца в зависимости от аргумента dir, который может принимать следующие значения: ios_base::beg – от начала файла;

* ios_base::cur – от текущей позиции;

* ios_base::end – от конца файла.

В следующем примере каждый вызов seekg() позиционирует файл на i-ую запись:

for ( int i = 0; i recordCnt; ++i )

readFile.ssekg( i * sizeof(Record), ios_base::beg );

С помощью первого аргумента можно задавать отрицательное значение. Переместимся на 10 байтов назад от текущей позиции:

readFile.seekg( -10, ios_base::cur );

Текущая позиция чтения в файле типа fstream возвращается любой из двух функций-членов tellg() или tellp(). Здесь 'p' означает запись (putting) и используется с объектом ofstream, а 'g' говорит о чтении (getting) и обслуживает объект ifstream:

// сохранить текущую позицию

ios_base::pos_type mark = writeFile.tellp();

// ...

if ( cancelEntry )

// вернуться к сохраненной позиции

writeFile.seekp( mark );

Если необходимо сместиться вперед от текущей позиции на одну запись типа Record, то можно воспользоваться любой из данных инструкций:

// эквивалентные вызовы seekg

readFile.seekg( readFile.tellg() + sizeof(Record) );

// данный вызов считается более эффективным

readFile.seekg( sizeof(Record), ios_base::cur );

Разберем реальный пример. Дан текстовый файл, нужно вычислить его длину в байтах и сохранить ее в конце файла. Кроме того, каждый раз при встрече символа новой строки требуется сохранить текущее смещение в конце файла. Вот наш текстовый файл:

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 ;