желтая методичка страница 13
Операторы ввода- вывода информации для файлов пользователей на дисках.
В имеющейся литературе основное внимание уделено операторам ввода и вывода для стандартных текстовых файлов. Нас же интересует, в первую очередь, файлы, состоящие из записей, структура которых задается пользователем. Причем, нас интересуют функции, прототипы которых описаны в стандартном библиотечном файле stdio.h. В литературе встречаются (довольно редко) функция чтения из файла -fread() и функция записи в файл fwrite(). Разберемся с этими функциями с помощью справочной системы Си (HELP). Заказав в этой системе поиска слово fread, получим следующую информацию:
Syntax
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
Description
Reads data from a stream.
fread reads n items of data each of length size bytes from the given input stream into a block pointed to by ptr.
The total number of bytes read is (n * size).
Return Value
On success fread returns the number of items (not bytes) actually read.
On end-of-file or error it returns a short count (possibly 0).
Давайте разберемся с этой информацией (а нам нужно уметь это делать!). Перевод этого текста можно представить в следующем виде:
Синтаксис
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
Описание
Читает данные из потока.
fread читает n записей, каждая размером size из потока stream в блок оперативной памяти, адрес которого находится в переменной ptr.
Общее количество читаемых файлов n* size.
Возвращаемое значение
В случае успешного чтения возвращает число фактически прочитанных записей ( не байтов!)
В конце файла или в случае ошибки возвращает нуль.
Сразу возникает вопрос «А что это за тип данных size_t ?». С помощью все той же системы HELP находим смысл слова size_t:
In Borland’s implementation of the ANSI C standard, the type size_t is unsigned.
Что означает следующее:
В приложениях на стандартном Си тип size_t означает тип unsigned (целое без знака). Ну этот тип мы с вами уже знаем.
Обратите внимание, что указание в синтаксисе включаемого файла (#include <stdio.h>) означает, что прототип рассматриваемой функции находится в библиотечном файле stdio.h.
Итак, из этого описания ясно, откуда нужно прочесть ( из потока stream), куда прочесть ( в блок памяти, на который указывает переменная ptr), и сколько байтов (n * size). Но ведь файл большой, n * size – это только какая то часть файла! Из какого места файла нужно прочесть n * size байтов? Вспомним рисунок 1. Там есть указатель текущей позиции файла. Обозначим его как UTP. Так вот как раз этот самый UTP указывает на тот байт в файле с которого нужно прочесть n * size байтов. Но ведь никакого UTP нет в описании заголовка функции fread! Да, зто так. Дело в том, что за UTP следит сама система. Нам только следует знать, используя оператор fread, что после открытия файла значение UTP равно нулю (т. е. он указывает на нулевую запись в файле, а затем меняется при каждом выполнении оператора fread() автоматически по формуле:
UTP = UTP + n * size.
Т. е. прочитав оператором fread() первый раз n записей, начиная с нулевой, в следующий раз оператор fread() прочтет n записей начиная с записи n. Если n = 1, то выполняяемый последовательно оператор fread() будет соответственно читать записи 0, 1, 2, и т. д.
Важно отметить еще одну особенность функции fread(). При его выполнении каждый раз формируется признак_окончания_файла, который равен нулю, если при выполнении функции fread() обнаружен код окончания файла. Этот признак_окончания_файла проверяется функцией feof (). Описание которой можно найти в справочной системе Си:
Синтаксис
#include <stdio.h>
int feof(FILE *stream);
Описание
Проверяет признак_конца_файла в потоке stream
Возвращаемое значение
Возвращаемое значение равно нулю, если признак_конца_файла был обнаружен при последнем выполнении функции fread(), в противном случае возвращаемое значение, не равное нулю.
Фугкция feof ().часто используется для организации циклов при просмотре файлов.