По теме лабораторной работы
Для реализации файлового ввода/вывода, необходимо включить в программу заголовочный файл <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. Каково назначение флагов форматирования? Какие средства реализованы в библиотеке для работы с флагами форматирования?