В файле, записи которого имеют фиксированную размерность, очень просто вычислять их смещение (адрес, позицию). Структуру такого файла можно усложнить, если сделать размерность записей зависимой от параметров, которые также можно хранить в том же файле, но "ближе к началу". Тогда можно получить структуру данных с варьируемой от файла к файлу размерностью. Работа с таким файлом происходит по принципу "раскрутки": читаются параметры, определяющие размерность следующей компоненты, в которой находятся новые параметры и т.д.. В качестве примера приведем фрагмент программы, работающей с файлом-таблицей с произвольным количеством и типами столбцов. Файл содержит целые переменные -количество столбцов и строк, затем соответствующее количество структурированных переменных -описателей столбцов, а затем сами строки таблицы.
//------------------------------------------------------bk59-02.cpp
// Параметризованный файл записей фиксированной длины
#include <stdio.h>
#include <alloc.h>
struct item // Описатель столбца
{
int type; // тип столбца
int size; // размерность столбца
char name[30]; // Имя столбца
};
struct TableDef // Описатель таблицы
{
FILE *fd; // Дескриптор файла
int ns; // Количество столбцов
int nr; // Количество строк
int strlnt; // Размер строки таблицы
int size0; // Смещение строк таблицы в файле
item *ST; // Динамический массив описателей
};
//------ Открыть файл и прочитать описатели столбцов -----
TableDef *OpenTable(char *name)
{ int i; // Ниже для простоты
TableDef *p; // отсутствуют многочисленные
p= new TableDef; // проверки результата функции
if ((p->fd = fopen(name,"rb+wb"))==NULL)
{ delete p; return NULL; } // Открыть файл
fread( (void*) &p->ns,sizeof(int),1,p->fd); // Чтение ns
fread( (void)&p->nr,sizeof(int),1,p->fd); // Чтение nr
p->ST= new item[p->ns];
fread(p->ST,sizeof(item),p->ns,p->fd); // Чтение массива описателей