Файлы произвольного доступа

Для выполнения произвольного доступа применяется функция fseek, позволяющая обрабатывать файл подобно массиву и непосредственно достигать любого определенного байта. Эта функция имеет вид:

fseek (stream, offset, origin);

stream – указатель на файл;

оrigin – указатель направления отсчета.

Функция перемещает (внутренний) указатель файла, связанного с потоком stream на новое место в файле, которое вычисляется по смещению offset и указанию направления отсчета origin.

Следующая операция с указанным потоком stream будет выполнена, начиная с той позиции, на которое произошло перемещение. Аргумент origin должен быть одной из следующих констант:

0 – начало файла;

1 – текущая позиция указателя файла;

2 – конец файла.

Для того, чтоб перемещать указатель, необходимо знать количество символов в записи. Для дальнейших рассуждений обозначим номер записи через n, а количество символов в записи – через m.

Рассмотрим ситуацию, когда origin = 0. Тогда для того, чтобы установить указатель на запись с номером n offset должен быть вычислен по следующей формуле:

оffset = (n-1)*m

Рассмотрим вторую ситуацию, когда origin = 1. Установим указатель на начало файла (offset=0). Для того, чтобы перейти на следующую (вторую) запись offset должен быть равен нулю. Для перехода с первой на третью запись offset = m и т.д.

Можно двигаться не только от начала к концу файла, но и в обратном направлении. Для этого offset должен быть отрицательным. Например, если указатель стоял на пятой записи, то для того, чтоб перейти на четвертую offset = -2*m, а для перехода с пятой на третью offset = -3*m и т.д.

Рассмотрим третью ситуацию, когда origin = 2. В этом случае указатель перемещается от конца файла. Параметр offset может быть как с плюсом, так и с минусом. Например, для того, чтобы переместить указатель на предпоследнюю запись, offset должен быть вычислен по формуле: offset = 2*m

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

handle =open (“имя файла”, O_CREATE);

l = file length (handle);

close (handle);

Переменная handle имеет тип int, а переменная 1 так же, как переменная offset – тип long. После выполнения приведённых выше операторов размер файла содержится в переменной 1. Для работы операторов, определяющих размер файла, перед программой необходимо добавить процедуры:

# include < fcnt.h >

# include < io.h >

На рисунке 2 представлена программа, демонстрирующая прямой доступ. Первая часть программы, обеспечивающая создание файла практически такая же, как и предыдущая. Исключение состоит в том, что для каждой переменной в операторе fprintf определён размер.

Длина записи определяется, как сумма размеров определённых переменных плюс единица, т.е. для нашего примера n = 28. Далее идёт группа операторов, определяющих длину файла.

Следом идёт оператор, инициализирующий переменную n. Переменная n несёт двойную нагрузку. С одной стороны она является признаком окончания цикла (входит в оператор while), с другой определяет номер записи. Затем вычисляется значение переменной offset по формуле, смысл которой описан выше. Эта формула применена в данной программе, т.к. используемый в дальнейшем оператор fseek работает в параметром origin равным нулю. Оператор if контролирует выход указателя за начало или конец файла. Если выведено значение n равное нулю, то цикл прекращается. Если произошёл выход за конец файла (offset >= 1), то игнорируются все последующие операторы цикла, но работу можно будет продолжать, т.е. ввести следующий номер записи. Если выход за пределы файла не произошёл, то выполняются операторы цикла, смысл которых не требует дополнительных пояснений.

# include <stdio.h>

# include <fcntl.h>

# include <io.h>

main ()

{char fio[10], gr [5];

float st;

long offset,l;

int p=1, handle, n;

FILE *lf;

clrscr ();

lf=fopen(“student.dat”,”w”);

while(p)

{

printf(“Введите сведения о студенте”);

printf(“\n Введите Ф.И.О.”);

scanf(“%s”,&fio);

printf(“\n Введите номер группы”);

scanf(“%s”,&gr);

printf(“\n Введите размер стипендии”);

scanf(“%s”,&st);

fprintf(lf,“%15s%6s%6.2f ”,fio,gr,st);

printf(“\n Признак окончания ввода”);

scanf(“%s”,&p);

}

fclose (lf);

handle = open(“student.dat”,O_CREAT);

l=filelength(handle);

close(handle);

n=1;

lf=fopen(“student.dat”,”r ”);

while(n)

{

printf (“Введите номер о записи”);

scanf (“%d”,&n);

offset=(n-1)*28;

if (offset>=1 | | n==0) continue;

fseek (lf,offset,0);

fscanf (lf,”%s %s %f ”,&fio,&gr,&st);

printf (“%15s%6s%6.2f\n”,fio,gr,st);

}

fclose(lf);

}

Рисунок 2 - Программа


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: