Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование / WORD / Лекции по ЯП (часть 3).doc
Скачиваний:
135
Добавлен:
15.04.2015
Размер:
1.34 Mб
Скачать

Запись и чтение данных

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

Используя форматированный вывод, можно сохранять данные в оформленном, упорядоченном виде. Этот способ допускается для использования только с текстовыми файлами. Основным применением форматированного вывода можно считать создание файлов текстовой и числовой информации типа электронных таблиц или баз данных.

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

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

Форматированный ввод-вывод Форматированный вывод

Форматированный вывод выполняется библиотечной функцией fprintf().

Прототип этой функции находится в заголовочном файле stdio.h и выглядит следующим образом:

Int fprintf (file *fp, char *fmt, ...);

Первым ее аргументом является указатель на структуру FILE. Для записи данных в конкретный файл следует передать в функцию указатель, возвращенный функцией fopen() при открытии файла.

Второй аргумент — это строка формата. Строки формата рассматривались при изучении функции printf().

Последний аргумент функции fprintf() представляет собой многоточие, которое обозначает переменный список аргументов. Дополнительные аргументы являются переменными или выражениями, значения которых следует вывести в заданный поток.

Если в качестве потока указать stdout, то различия между работой функций printf() и fprintf() исчезнут.

Форматированный ввод

Для форматированного ввода используется библиотечная функция fscanf(), совершенно аналогичная по своему назначению функции scanf().с тем исключением, что ввод выполняется из заданного файлового потока, а не из stdin. Прототип функции fscanf():

int fscanf (FILE *fp, const char *fmt, ...);

Аргумент fp — это указатель структурного типа FILE, возвращенный из fopen(), a fmt — указатель на строку формата, задающую правила считывания потока ввода. Строка формата устроена точно так же, как и в функции scanf (). Наконец, многоточие (...) указывает на наличие еще одного или нескольких дополнительных аргументов — адресов переменных, в которые следует поместить введенные данные.

Символьный ввод

Для символьного ввода из файлов в языке С имеется три функции: getc() и fgetc() считывают одиночные символы, a fgets() — строки символов.

Функции getc() и fgetc().

Эти две функции полностью идентичны и взаимозаменяемы. Они вводят один символ из заданного потока ввода. Прототип функции getc() находится ле stdio.h и имеет следующий вид:

int getc (FILE *fp);

Аргумент fр — это указатель на поток ввода, возвращенный из функции fopen() при открытии файла. Функция возвращает введенный символ или EOF в случае ошибки.

Если функции getc() и f getc() возвращают одиночный символ, то почему возвращаемые ими значения имеют тип int? Причина заключается в том, что при чтении из файла нужно иметь возможность считывать и распознавать признак конца файла, который в некоторых системах имеет тип int, а не char.

Чтобы прочитать текстовый файл, можно использовать конструк­цию

ch=getc(fp);

while(ch!=EOF)

{ ch=getc(fptr)};

Когда считывается двоичный файл, то определить наличие конца фай­ла, так же как при чтении текстового файла, не удается. Для определения конца текстового файла служит функция feof() с прототипом

int feof(FILE *fptr):

Функция возвращает значение "истинно", если конец файла достигнут, и "нуль" в противном случае. Следующая конструкция читает двоичный файл до конца файла:

While (!feof(fp))

{ ch=getc(fptr); }

Для текстовых файлов эта конструкция также применима.

Функция fgets()

Для чтения строки символов из файла используется библиотечная функция fgets (). Она имеет следующий прототип:

char *fgets(char *str, int n, FILE *fp);

Аргумент str представляет собой указатель на буфер, в который следует поместить введенную строку;

n —максимальное число символов, которое разрешается ввести;

fp — указатель на структуру FILE, возвращенный из функции fopen() при открытии файла.

Функция fgets() считывает символы из потока fp в память, начиная с адреса в указателе str. Символы считываются до тех пор, пока не встретится символ новой строки или пока не будет прочитано n-1 символов. Ввод заканчивается тогда, когда случается первое из этих событий. Установив n равным количеству байт, выделенных для буфера str, мы предотвращаем переполнение буфера и запись в неразрешенные области памяти. Вводится именно n-1, а не n символов, чтобы в буфер поместился еще и нулевой завершающий символ \0, который автоматически добавляется в конец строки функцией fgets(). После успешного завершения ввода fgets() возвращает указатель str. Значение NULL возвращается в одном из двух случаев:

  • прежде чем функция ввела хотя бы один символ, встретился конец файла (EOF) или произошла другая ошибка ввода. В этом случае содержимое буфера str остается нетронутым;

  • функция fgetc() успела ввести один или несколько символов в буфер str, а затем встретился конец файла или произошла другая ошибка. Тогда после возвращения NULL буфер str содержит случайный набор символов.

Как видите, функция fgets() не всегда вводит целую строку (т.е. последовательность символов до символа конца строки). Если ввод n-1 символа закончился раньше, чем встретился конец строки, то fgets() завершается. Следующая операция ввода из файла начинается с того же места, на котором завершилась предыдущая. Для гарантированного ввод целых строк необходимо позаботься о том, чтобы размер буфера и количество символов n были достаточно большими.