Файловый ввод/вывод
Если программе необходимо работать с файлом, то следует включить в нее заголовочный файл 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; - ассортиментный список дамской обуви с указанием наименования и имеющегося в наличии числа пар каждой модели. |