Лабораторная работа №8 "Блоковый ввод-вывод" Цель: Работа с двоичными файлами, организация ввода-вывода структурированной информации и ее хранение на внешних носителях.
1. Краткие теоретические сведения
1. 1. Ввод и вывод в Си
Особенностью Си является отсутствие в этом языке структурированных файлов. Все файлы рассматриваются как не структурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.
В Си отсутствуют средства ввода-вывода. Все операции ввода-вывода реализуются с помощью функций, которые находятся в библиотеке Си. Библиотека Си поддерживает три уровня ввода-вывода:
потоковый ввод-вывод;
ввод-вывод нижнего уровня;
ввод-вывод для консоли и портов (зависит от ОС).
1.2. Потоковый ввод-вывод
На уровне потокового ввода-вывода обмен данными производится побайтно, т. е. за одно обращение к устройству (файлу) производится считывание или запись фиксированной порции данных (512 ил 1024 байта). При вводе с диска или при считывании из файла данные помещаются в буфер ОС, затем побайтно или порциями передаются в программе пользователя. При вывод в файл данные накапливаются в буфере, а при заполнении буфера записываются в виде единого блока на диск. Буферы ОС реализуются в виде участков основной памяти . Функции библиотеки Си, поддерживающие обмен, с данными на уровне потока позволяют обрабатывать данные различных размеров и форматов.
Поток - это файл вместе с предоставленными средствами буферизации. При работе с потоком можно:
Открывать и закрывать потоки ( связывать указатели на поток с конкретными файлами);
вводит и выводить строку, символ, форматированные данные, порцию данных произвольной длины;
анализировать ошибки ввода-вывода и достижения конца файла;
управлять буферизацией потока и размером буфера;
получать и устанавливать указатель текущей позиции в файле;
Функции библиотеки ввода-вывода находятся в заголовочном файле .
1.3. Открытие и закрытие потока
Прежде чем начать работать с потоком, его надо инициировать, т. е. открыть. При этом поток связывается со структурой предопределенного типа FILE, определение которой находится в библиотечном файле . В структуре находится указатель на буфер, указатель на текущую позицию файла и т. п. При открытии потока, возвращается указатель на поток, т. е. на объект типа FILE.
#include ;
. . . . . . . .
FILE *fp;
. . . . . . . . . . ..
fp= fopen( ”t.txt”, ”r”);
где fopen(<имя_файла>,<режим_открытия>) - функция для инициации файла.
Существуют следующие режимы для открытия файла:
”w” - открыть файл для записи, если файл существует, то он стирается;
”r” - открыть файл для чтения;
”a” - открыть файл для добавления, если файл существует, то он не стирается и можно писать в конец файла;
”w+” - открыть файл для записи и исправления, если файл существует, то он стирается, а далее можно и читать , и писать, размеры файла можно увеличивать;
”r+” - открыть файл для чтения и записи, но увеличить размер файла нельзя;
”a+” - открыть файл для добавления, т. е. можно и читать и писать, в том числе и в конец файла.
Поток можно открыть в текстовом (t) или двоичном (b) режиме. По умолчанию - текстовый режим. В явном виде режим указывается следующим образом: ”r+b”или ”rb” - двоичный (бинарный) режим.
Пример:
if ((fp=fopen(”t.txt”, ”w”)==NULL)
{
perror(”\nошибка при открытии файла”); // выводит строку символов с сообщением // об ошибке
exit(0);
}
После работы с файлом, его надо закрыть
fclose(<указатель_на_поток>);
Блоковый ввод-вывод
Для блокового ввода и вывода используются функции :
int fread( void *ptr, int size, int n, FILE *fp) , где
void *ptr - указатель на область памяти, в которой размещаются считываемые из файла данные;
int size - размер одного считываемого элемента;
int n - количество считываемых элементов;
FILE *fp - указатель на файл, из которого производится считывание.
В случае успешного считывания информации функция возвращает число прочитанных элементов (а не байтов), иначе возвращает EOF.
2) int fwrite( void *ptr, int size, int n, FILE *fp) , где
void *ptr - указатель на область памяти, в которой размещаются записываемые в файл данные;
int size - размер одного записываемого элемента;
int n - количество записываемых элементов;
FILE *fp - указатель на файл, в который производится запись.
В случае успешной записи информации функция возвращает число записанных элементов, иначе возвращает EOF.
Пример:
. . . .. . . ..
typedef STRUCT
{
char name [40];
char post [40];
float rate;
}EMPLOYEE;
void main ()
{
FILE *f; // указатель связанный с файлом
EMPLOYEE e; // переменная
EMPLOYEE mas[10] //массив
//открываем файл
if ((f=fopen("f.dat", "wb")==NULL) exit(1); // если при открытии файла возникает
//ошибка, то выходим из функции
int i;
for(i=1; i<=10;i++)
{
//формируем запись е
printf("name="); scanf("%s",&e.name);
printf("post="); scanf("%s",&e.post);
printf("rate="); scanf("%f",e.rate);
// записываем запись е в файл
fwrite(&e, sizeof(EMPLOYEE),1,f);
if (ferror(f)==NULL) exit(2);
}
fclose(f);
//чтение записей из файла
if ((f=fopen("f.dat", "rb")==NULL) exit(3); // если при открытии файла возникает
//ошибка, то выходим из функции
i=0;
while(!feof(f)&&i<=10)
{
fread(&mas[i], sizeof(EMPLOYEE),1,f);
i++;
}
fclose(f);
}
2. Постановка задачи
Сформировать двоичный файл из элементов, заданной в варианте структуры, распечатать его содержимое, выполнить удаление и добавление элементов в соответствии со своим вариантом, используя для поиска удаляемых или добавляемых элементов функцию. Формирование, печать, добавление и удаление элементов оформить в виде функций. Предусмотреть сообщения об ошибках при открытии файла и выполнении операций ввода/вывода.
3. Варианты
Структура "Абитуриент":
фамилия, имя, отчество;
год рождения;
оценки вступительных экзаменов (3);
средний балл аттестата.
Удалить элемент с указанным номером, добавить элемент после элемента с указанной фамилией.
Структура "Сотрудник":
фамилия, имя, отчество;
должность
год рождения;
заработная плата.
Удалить элемент с указанной фамилией, добавить элемент после элемента с указанным номером.
Структура "Государство":
название;
столица;
численность населения;
занимаемая площадь.
Удалить все элементы, у которых численность меньше заданной, добавить элемент после элемента с указанным номером.
Структура "Человек":
фамилия, имя, отчество;
домашний адрес;
номер телефона;
возраст.
Удалить все элементы с заданным возрастом, добавить элемент после элемента с заданным номером.
Структура "Человек":
фамилия, имя, отчество;
год рождения;
рост;
вес.
Удалить все элемент с указанным ростом и весом, добавить элемент после элемента с указанной фамилией.
Структура "Школьник":
фамилия, имя, отчество;
класс;
номер телефона;
оценки по предметам (математика, физика, русский язык, литература).
Удалить все элементы, у которых есть 2 хотя бы по одному предмету, добавить элемент в начало файла.
Структура "Студент":
фамилия, имя, отчество;
домашний адрес;
группа;
рейтинг.
Удалить все элементы, у которых рейтинг меньше заданного, добавить 1 элемент в конец файла.
Структура "Покупатель":
фамилия, имя, отчество;
домашний адрес;
номер телефона;
номер кредитной карточки.
Удалить 3 элемента из начала файла, добавить 3 элемента в конец файла.
Структура "Пациент":
фамилия, имя, отчество;
домашний адрес;
номер медицинской карты;
номер страхового полиса.
Удалить элемент с заданным номером медицинской карты, добавить 2 элемента в начало файла.
Структура "Информация":
носитель;
объем;
название;
автор.
Удалить первый элемент с заданным объемом информации, добавить элемент перед элементом с указанным номером.
Структура "Видеокассета":
название фильма;
режиссер;
продолжительность;
цена.
Удалить все элементы с ценой выше заданной, добавить 3 элемента в конец файла.
Структура "Музыкальный диск":
название;
автор;
продолжительность;
цена.
Удалить первый элемент с заданной продолжительностью, добавить 2 элемента после элемента с заданным номером.
Структура "Спортивная команда":
название;
город;
количество игроков;
количество набранных очков.
Удалить все элементы с количеством очков меньше заданного, добавить 2 элемента в начало файла.
Структура "Стадион":
название;
адрес;
вместимость;
виды спорта.
Удалить элемент с заданным названием, добавить 2 элемента после элемента с указанным номером.
Структура "Автомобиль":
марка;
год выпуска;
цена;
цвет.
Удалить все элементы, у которых год выпуска меньше заданного, добавить элемент в начало файла.
Структура "Владелец автомобиля":
фамилия, имя, отчество;
номер автомобиля;
телефон;
номер техпаспорта.
Удалить элемент с заданным номером, добавить 2 элемента перед элементом с заданной фамилией.
Структура "Фильм":
название;
режиссер;
год выпуска;
стоимость.
Удалить все элементы, у которых стоимость превышает заданную, добавить элемент в начало файла.
Структура "Книга":
название;
автор;
год издания;
количество страниц.
Удалить 3 элемента из начала файла, добавить элемент перед элементом с указанным названием.
Структура "Фильм":
название;
режиссер;
страна;
приносимая прибыль.
Удалить 2 элемента из конца файла, добавить элемент после элемента с указанным названием.
Структура "Государство":
название;
государственный язык;
денежная единица;
курс валюты относительно $.
Удалить элемент с указанным названием, добавить 2 элемента в конец файла.
Структура "Автомобиль":
марка;
серийный номер;
регистрационный номер;
год выпуска.
Удалить 3 элемента из начала файла, добавить элемент поле элемента с указанным регистрационным номером.
Структура "Владелец автомобиля":
фамилия, имя, отчество;
номер автомобиля;
номер техпаспорта;
отделение регистрации ГАИ.
Удалить элемент с заданным номером, добавить 2 элемента перед элементом с заданной фамилией.
Структура "Стадион":
название;
год постройки;
количество площадок;
виды спорта.
Удалить все элементы, у которых год постройки меньше заданного, добавить 2 элемента перед элементом с указанным номером.
Структура "Студент":
фамилия, имя, отчество;
номер телефона;
группа;
оценки по 3 основным предметам.
Удалить все элементы из группы с указанным номером, у которых среднее арифметическое оценок меньше заданного, добавить элемент после элемента с заданной фамилией.
Структура "Студент":
фамилия, имя, отчество;
дата рождения;
домашний адрес;
рейтинг.
Удалить элементы, у которых даты рождения совпадают, добавить элемент перед элементом с заданной фамилией. 4. Методические указания
Для заполнения файла можно использовать функцию, формирующую одну структуру, указанного в варианте типа. Значения элементов структуры вводятся с клавиатуры. Для ввода можно использовать операцию >> и функцию gets().
При вводе структур можно реализовать один из следующих механизмов:
ввод заранее выбранного количества структур (не менее 5);
ввод до появления структуры с заданным количеством признаков;
диалог с пользователем о необходимости продолжать ввод.
Для записи структуры в файл и чтения структуры из файла использовать функции блочного ввода/вывода fread и fwrite.
Для удаления/ добавления элементов в файл использовать вспомогательный файл.
5. Содержание отчета
Постановка задачи.
Описание используемых типов данных.
Текст функций для:
формирования файла,
печати файла,
добавления записи в файл,
удаления записи из файла
поиска структуры для удаления.
4. Результат решения конкретного варианта.
|