Форматный ввод и вывод в файл
Для записи информации в файл и ее чтения из файла могут использоваться различные функции. Среди библиотечных функций имеются fprintf и fscanf, которые обеспечивают форматный ввод-вывод. По принципу работы они аналогичны printf и scanf, но имеют один дополнительный аргумент (первый по счету) — указатель на структуру FILE, соответствующую используемому потоку.
int fprintf(FILE* fp, char* форматная_строка [,argument, ...]);
int fscanf(FILE* fp, char* форматная_строка [,address, ...]);
ЗАДАНИЕ 1
1. Создается новый файл с именем test.txt, для этого открыть файл с этим именем в режиме, поддерживающем создание новых файлов.
2. С помощью fprintf вывести в этот файл строку "Hello" и закрыть файл.
3. Открыть файл test.txt в режиме для чтения и дополнения. С помощью fprintf в него дописывается символ новой строки и число — текущий год.
4.
число и ся символ новой строки и текущий
годнить
5. Закрыть файл. Просмотреть содержание полученного файла с помощью файловой системы.
Замечание
После каждой операции открытия файла должна следовать проверка результата выполнения функции.
Произвольный доступ к файлу
Библиотека Си обеспечивает как последовательный, так и произвольный доступ к файлам. Произвольный доступ основан на позиционировании указателя чтения-записи, поддерживаемого функциями стандартного уровня.
а) Изменение позиции указателя текущей позиции чтения-записи.
Для изменения значения текущей позиции используется функция fseek:
int fseek(FILE* fp, long int offset, int origin);
Для файла, заданного fp, функция назначает новую текущую позицию, которая рассчитывается исходя из базы отсчета (origin) и смещения относительно нее (offset).
База для отсчета задается одной из трех констант (определены в stdio.h):
SEEK_SET — отсчёт ведётся от начала файла,
SEEK_CUR — отсчёт ведётся от текущей позиции чтения-записи,
SEEK_END — отсчёт ведётся от конца файла.
Функция fseek возвращает значение 0, если указатель файла успешно перемещён, и ненулевое значение в случае неудачного выполнения.
Установить указатель чтения-записи на начало файла можно также с помощью функции
void rewind(FILE *fp);
которая действует аналогично вызову fseek(fp,0,SEEK_SET).
б) Получение текущей позиции указателя чтения-записи
Узнать положение указателя чтения-записи позволяет функция ftell, которая возвращает смещение текущей позиции указателя в байтах по отношению к началу файла:
long int ftell(FILE *fp);
В случае ошибки функция возвращает EOF (т.е. -1).
Определение длины файла
В библиотеке стандартного уровня нет специальной функции для определения длины файла. Поэтому для вычисления длины файла приходится прибегать к сочетанию вызовов fseek и ftell (как это можно сделать?).
Однако в библиотеке системного уровня (заголовочный файл io.h) есть функция
long filelength(int handle),
которая решает эту задачу.
Как уже указывалось, функции системного уровня основывают свою работу не на структуре типа FILE, а на значении дескриптора (handle) файла. Хотя в структуре FILE есть поле, хранящее значение дескриптора, обращаться к этой структуре напрямую строго не рекомендуется, так как структура с развитием стандарта языка может быть со временем изменена, и тогда программа потеряет работоспособность.
Вместо этого значение дескриптора из структуры можно безопасно получить с помощью еще одной функции стандартного уровня:
int fileno(FILE* fp);
Таким образом, длина файла может быть получена также сочетанием вызовов fileno и filelength.
ЗАДАНИЕ 2
1. Написать функции long filesize1(FILE*) и long filesize2(FILE*) для вычисления длины файла двумя способами: с помощью позиционирования внутреннего указателя на конец файла (после выхода из функции указатель должен восстановить свое положение) и, используя функцию filelength.
2. В функции main описать символьную строку s вида 1234567890. Открыть новый файл lab.dat в режиме "запись-чтение" и вывести в него s. Вывести длину файла, полученную функциями filesize1 и filesize2. Заменить в файле один из символов на A. Позиция символа вводится в диалоге и проверяется по длине файла ее допустимость. Прочесть измененную строку из файла в s, и напечатать ее. Закрыть файл.
3. Открыть файл lab.dat в режиме "добавление-чтение". Занести в него три произвольных символа и вывести новую длину файла (filesize1 или filesize2). Прочесть пять последних символов в файле, и напечатать их. Закрыть файл lab.dat.
4. Открыть два новых файла (lab1.dat и lab2.dat) для записи, один в текстовом, а другой в двоичном режимах. Записать в каждый из них по 10 раз комбинацию из символа A и символа \n. Напечатать длину каждого из файлов с пояснением о режиме открытия. Пояснить результаты.