По теме лабораторной работы

Для реализации файлового ввода/вывода, необходимо включить в программу заголовочный файл <fstream.h>, в котором определено несколько классов, включая ifstream, ofstream иfstream.

В C++ файл открывается посредством его связывания с потоком. Имеется три типа потоков: ввода, вывода и ввода/вывода. Перед тем как открыть файл, нужно, во-первых, создать поток. Для создания потока ввода необходимо объявить объект типа ifstream. Для создания потока вывода - объект типа ofstream. Потоки, которые реализуют одновременно ввод и вывод должны объявляться как объекты типа fstream.

Например:

ifstream fin; // создание потока ввода

ofstream fout; // создание потока вывода

ifstream fio; // создание потока ввода/вывода

После создания потока, одним из способов связать его с файлом является использование функции ореn- Эта функция является членом каждого из трех потоковых классов. ifstream fio; // создание потока ввода/вывода

Прототипы данной функции для каждого класса такие: классов.

void ifstream: :open( char *имя_файла, open

mode режим = ios:: in);

void ofstream: :open( char *имя_файла, open

mode режим = ios:: out; ios::trunc);

void fstream::open( char *имя_файла, open

mode режим = ios::in | ios::out);

Здесь имя файла - имя файла, в которое может входить ид спецификатор пути. Значение режима задает режим открытия файла. Оно должно быть значением типа openmode, которое является перечислением, определенным в классе ios. Значение режим может быть одним из следующих:

ios::app ios:: ate ios:: binary ios:: in

ios::nocreate ios:: noreplace ios::trunkos::app - открытие файла в режиме добавления в конец файла. Это значение может применяться только к файлам, открываемым для записи (записи информации в файл);

ios::ate - поиска конеца файла при его открытии. Хотя данное значение вызывает поиск конца файла, тем не менее, операции ввода/вывода могут быть выполнены в любом месте файла;

ios::in - открытие файла для ввода (чтения информации из файла); ios::out открытие файла для вывода (записи информации в файл); ios::binary - открытие файла в двоичном режиме. По умолчанию все файлы открываются в текстовом режиме. В текстовом режиме имеет место преобразование некоторых символов,например,

последовательность символов "возврат каретки/перевод строки" превращается в символ новой строки. Если же файл открывается в двоичном режиме, такого преобразования не выполняется. Любой файл, независимо от того, что в нем содержится - отформатированный текст или необработанные данные - может быть открыть как в текстовом, так и в двоичном режиме. Отличие между ними только в отсутствии или наличии упомянутого символьного преобразования;

ios::nocreate - не открывать новый файл. Открытие терпит неудачу, если файл не существует;

ios:: no replace - не открывать существующий файл. Открытие терпит неудачу, если файл существует;

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

Пример открытия файла prim.txt для вывода: ofstream mystream;//создание потока вывода

mystream.open("prim.txt"); // связывание потока вывода с файлом prim.txt

В этом примере параметр режим функции openQ по умолчанию устанавливается в значение, соответствующее типу открываемого потока, поэтому нет необходимости указывать его явно.

Как правило, перед тем как пытаться получить доступ к файлу, следует проверить результат выполнения функции ореn().

Для проверки правильности открытия файла используют операцию НЕ (!).

Пример проверки открытия файла с помощью операции НЕ: if (! mystream)

{ cerr « "Не удалось открыть файл\п";// программа обработки ошибки открытия файла }

Для открытия файлов помимо функции ореn() можно использовать конструкторы классов ifstream, ofstream иfstream, которые открывают файлы автоматически. Конструкторы имеют те же параметры, в том числе и задаваемые по умолчанию, что и функция ореn() можно использовать конструкторы классов ifstream, ofstream иfstream, которые открывают файлы автоматически. Конструкторы имеют те же параметры, в том числе и задаваемые по умолчанию, что и функция ореn()

Пример открытия файла pfiml.txt для ввода (чтения из файла) с помощью конструктора: ifstream fi("priml.txt");

Для закрытия файла используется функция eloseQ . Например, для закрытия файла, связанного с потоком fi используется инструкция: fi.closeO;

После того как файл открыт, в него можно записать или прочитать из него данные. Для этого можно использовать операторы « и » так же, как это делалось для консольного ввода/вывода, только следует заменить поток cin или cout тем потоком, который связан с файлом. Однако в C++ для работы с файлами поддерживается широкий диапазон функций ввода/вывода.

Получить информацию о текущем состоянии ввода/вывода можно с помощью следующих функций:

int rdstateO; - возвращает текущее состояние потока;

int eof(); - возвращает ненулевое значение при условии достижения конца файла (установлен флаг eofbit);

int fail(); - возвращает ненулевое значение, если операция терпит неудачу (установлен флаг failbit);

int badO; - возвращает ненулевое значение, если произошла ошибка (установлен флаг badbit);

int goodO; - возвращает ненулевое значение, если не установлен ни один флаг состояния (ошибок нет);

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

void clear (int =0); - устанавливает состояние потока в нуль.

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

 

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

# include <iostream.h>

# include <fstream.h>

# include <string.h>

# include <iomanip.h>

# include <stdlib.h>

const int N=200;

struct student {

char name [30];

int kurs;

char group[7];};

ofstream fout; // выходной файловый поток

// Прототипы функций void inputstudentfile (student pst[], int &m); void outputstudent (student pst[], int m); void outputstudent (student pst[], int m); void output (student stud, int m); void outputfile (student stud, int m);

// Ввод исходного массива задолжников из файла

void inputstudentfile (student pst[], int &m)

{

ifstream fin; // входной файловый поток

char file[10]; // имя входного файла

char iniz[7]; // рабочая переменная для инициалов

cout « ’’Имя файла:” ; cin » file; fm.open(file);

if( fin==NULL) {соиК<’'Файл не открыт.\n”; exit(l);}

m=0;

do {

fin » pst[i].name » iniz » pst[i].kurs » pst[i].gr ; strcat( pst[i].name, “ “); // добавление инициалов через

strcat( pst[i].name, iniz); // пробел к фамилии

m++;

}while (fin.goodQ); m-;

fin.close();

}

// Вывод массива задолжников на экран void outputstudent (student pst[], int m)

{

cout« “Фамилия и инициалы Курс Г руппа \п”; for (i=0; i<m; i++)

cout « setw(16)« pst[i].name « setw(7)« pst[i].kurs « setw(8) « pst[i].gr « endl;

11 Функция печати одной строки результатов на экран void output (student stud, int m)

{

cout« setw(4)« m « setw(16)« stud.name « endl;

}

// Функция печати одной строки результатов в файл void outputfile (student stud, int m)

{

fout « setw(4)« m « setw(16)« stud.name « endl;

}

// Основная функция программы

#include <string.h> void main()

{

student st[N];

int n, i, k; /* n - число строк в таблице

k - номер задолжника заданной группы i - индексная переменная */ char gr[7]; // заданная группы

char file[10]; // Имя выходного файла

inputstudentfile ( st, n); // ввод таблицы

cout « ” Исходный массив структур. \п” ; outputstudent ( st, n); // вывод таблицы на экран

cout « “Номер группы: ”; с in » gr; // заданная группа

cout «’’Имя выходного файла:” ; cin » file; fout.open(file);

if( !fout.good()) {сои1«”Файл не открытЛп”; exit(l);} k =0;

for (i = 0; i < n; i++) if (strcmp(st[i].group, gr) = 0)

{

k++; output(st[i], k); outputfile(st[i], k);

}

fout.close();

cout « “\n\n В группе “ « gr «” ”« k « “задолжников.\п

}

Задания для лабораторной работы:

Задание соответствет лабораторной работе №26-27, необходимо добавить считывание из файла и запись в файл.

 

Контрольные вопросы:

1. В каких состояниях может находиться поток? Каким образом отслеживается состояние конца потока?

2. Каким образом строковые потоки можно использовать для ограничения ширины поля ввода?

3. Перечислите средства форматирования объектно-ориентированной библиотеки.

4. Каким образом ввести строку типа st г i ng с пробелами?

5. Каково назначение флагов форматирования? Какие средства реализованы в библиотеке для работы с флагами форматирования?