Файловый ввод/вывод

 

Если программе необходимо работать с файлом, то следует включить в нее заголовочный файл fstream (который в свою очередь включает iostream):

#include <fstream>

 

Если файл будет использоваться только для вывода, мы определяем объект класса ofstream. Например:

ofstream outfile( "copy.out", ios_base::out );

 

Передаваемые конструктору аргументы задают имя открываемого файла и режим открытия. Файл типа ofstream может быть открыт либо – по умолчанию – в режиме вывода (ios_base::out), либо в режиме дозаписи (ios_base::app). Такое определение файла outfile2 эквивалентно приведенному выше:

// по умолчанию открывается в режиме вывода

ofstream outfile2( "copy.out" );

 

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

 

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

if ( ! outfile ) { // открыть файл не удалось

cerr <<"не могу открыть "copy.out" для записи\n";

exit( -1 );

}

 

Класс ofstream является производным от ostream. Все определенные в ostream операции применимы и к ofstream. Например, инструкции

char ch = ' ';

outFile.put( '1' ).put( ')' ).put( ch );

outFile <<"1 + 1 = " << (1 + 1) << endl;

 

выводят в файл outFile последовательность символов:

1) 1 + 1 = 2

 

Следующая программа читает из стандартного ввода символы и копирует их в файл:

#include <fstream>

int main()

{

// открыть файл copy.out для вывода

ofstream outFile( "copy.out" );

if ( ! outFile ) {

cerr << "Не могу открыть 'copy.out' для вывода\n";

return -1;

}

char ch;

while ( cin.get( ch ) )

outFile.put( ch );

}

 

К объекту класса ofstream можно применять и определенные пользователем экземпляры оператора вывода. Данная программа вызывает оператор вывода класса WordCount из предыдущего раздела:

#include <fstream>

#include "WordCount.h"

int main()

{

// открыть файл word.out для вывода

ofstream oFile( "word.out" );

// здесь проверка успешности открытия ...

// создать и вручную заполнить объект WordCount

WordCount artist("Renoir" );

artist.found( 7, 12 ); artist.found( 34, 18 );

// вызывается оператор <<(ostream&, const WordCount&);

oFile <<artist;

}

 

Чтобы открыть файл только для чтения, применяется объект класса ifstream, производного от istream. Следующая программа читает указанный пользователем файл и копирует его содержимое на стандартный вывод:

#include <fstream>

#include <string>

int main()

{

cout << "filename: ";

string file_name;

cin>> file_name;

// открыть файл для ввода

ifstream inFile( file_name.c_str() );

if ( !inFile ) {

cerr < <"не могу открыть входной файл: "

<<file_name << " -- аварийный останов!\n";

return -1;

}

char ch;

while ( inFile.get( ch ))

cout.put( ch );

}

 

Чтобы закрыть файл (отключить от программы), вызываем функцию-член close():

#include

const int fileCnt = 5;

string fileTabl[ fileCnt ] = {

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

};

int main()

{

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

for ( int ix = 0; ix < fileCnt; ++ix )

{

inFile.open( fileTabl[ix].c_str() );

// ... проверить успешность открытия

// ... обработать файл

inFile.close();

}

}

бъект класса fstream (производного от iostream) может открывать файл для ввода или вывода.

Объект класса 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.seekg( 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 );

Варианты заданий

Дан файл f, компоненты которого являются целыми числами. Записать в файл g, компоненты файла f, исключив повторные вхождения чисел.
Дан файл f, компоненты которого являются действительными числами. Найти: - наибольшее из значений компонентов f; - наименьшее из значений компонентов с четными номерами; - наибольшее из значений модулей компонентов с нечетными номерами; - сумму наибольшего и наименьшего из значений компонентов файла f; - разность первой и последней компоненты файла f.
Дан символьный файл f. Подсчитать число вхождений в файл каждой из букв a, b, c, d, e, f. Результат вывести в файл g в виде таблицы с комментариями.
Дан файл f, компоненты которого являются целыми числами. Записать в файл g все четные числа исходного файла, в файл h - все нечетные. Порядок следования чисел сохраняется. Записать в файл g и h комментарии.
Дан текстовый файл, содержащий программу на языке С. Проверить эту программу на соответствие числа открывающих и закрывающих фигурных скобок.
Дан символьный файл f. Найти и записать в файл g самое длинное слово файла f, снабдив его комментарием.
Дан файл f, компоненты которого являются целыми числами. Получить в файле g все компоненты файла f: - являющиеся четными числами; - делящиеся на 3 и не делящиеся на 7; - являющиеся точными квадратами. - Записать в файл g комментарий.
Дан файл f. Создать два файла, записав в первый из них все четные числа, расположив их в порядке возрастания, а во второй - все нечетные, расположив их в порядке убывания.
Дан текстовый файл f. Переформатировать исходный файл, разделяя его на строки так, чтобы каждая строка содержала столько символов, сколько содержит самая короткая строка исходного файла.
Дан файл f. Создать два файла, записав в первый из них среднее геометрическое всех четных чисел, а во второй - среднее арифметическое всех нечетных чисел.
Дан числовой файл f. Выбрать все значения, которые делятся нацело на 2 и 4, но не делятся на 6. Записать эти значения в файл g, а все остальные - в файл h.
Дан текстовый файл f. Определить, являются ли первые два символа цифрами и если да, то четно ли это число. Записать его в файл g, если оно четно и в h ,если оно нечетно.
Дан текстовый файл f. Создать новый файл g и переписать в него исходный файл в обратном порядке, разделив пробелами.
Сформировать массив на диске, содержащий сведения о пациентах глазной клиники. Структурный тип содержит поля: фамилия пациента, пол, возраст, место проживания (город), диагноз. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран: - количество иногородних, прибывших в поликлинику; - список пациентов старше Х лет с диагнозом J.
Сформировать массив на диске, содержащий сведения о сотрудниках института. Структурный тип содержит поля: фамилия работающего, название отдела, год рождения, стаж работы, должность, оклад. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран: - список сотрудников пенсионного возраста на сегодняшний день с указанием стажа работы; - средний стаж, работающих в отделе Х.
Сформировать массив на диске, содержащий сведения об отправлении поездов дальнего следования с Казанского вокзала. Структурный тип содержит поля: номер поезда, станция назначения, время отправления, время в пути, наличие билетов. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран: - время отравления поездов в город Х во временном интервале от А до В часов; - наличие билетов на поезд с номером ХХХ.
Сформировать массив на диске, содержащий сведения о том, какие из пяти предлагаемых дисциплин по выбору желает изучать студент. Структурный тип содержит поля: фамилия студента, индекс группы, пять дисциплин, средний балл успеваемости. Выбираемая дисциплина отмечается символом 1, иначе - пробелом. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран список студентов, желающих прослушать дисциплину X. Если число желающих превышает 4 человека, то отобрать студентов, имеющих более высокий средний балл успеваемости.
Сформировать массив на диске, содержащий сведения о нападающих команды «Спартак». Структурный тип содержит поля: имена нападающих, число заброшенных ими шайб, число сделанных голевых передач, заработанное штрафное время. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран четырех лучших игроков по сумме очков (голы + передачи).
Сформировать массивна диске, содержащий сведения об ассортименте обуви в магазине фирмы. Структурный тип содержит поля: артикул, наименование, количество, стоимость одной пары. Артикул начинается с буквы Д - для дамской обуви, М - для мужской, П - для детской. Написать программу, которая выбирает необходимую информацию с диска и выводит на экран: - сведения о наличии и стоимости обуви артикула X; - ассортиментный список дамской обуви с указанием наименования и имеющегося в наличии числа пар каждой модели.