Информатика и технология программирования

       

Параметризованные файлы записей фиксированной длины


В файле, записи которого имеют фиксированную размерность, очень просто вычислять их смещение (адрес, позицию). Структуру такого файла можно усложнить, если сделать размерность записей зависимой от параметров, которые также можно хранить в том же файле, но "ближе к началу". Тогда можно получить структуру данных с варьируемой от файла к файлу размерностью. Работа с таким файлом происходит по принципу "раскрутки": читаются параметры, определяющие размерность следующей компоненты, в которой находятся новые параметры и т.д.. В качестве примера приведем фрагмент программы, работающей с файлом-таблицей с произвольным количеством и типами столбцов. Файл содержит целые переменные -количество столбцов и строк, затем соответствующее количество структурированных переменных -описателей столбцов, а затем сами строки таблицы.


//------------------------------------------------------bk59-02.cpp


// Параметризованный файл записей фиксированной длины


&#35include &#60stdio.h&#62
&#35include &#60alloc.h&#62
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-&#62fd = fopen(name,"rb+wb"))==NULL)
{ delete p; return NULL; } // Открыть файл


fread( (void*) &#38p-&#62ns,sizeof(int),1,p-&#62fd); // Чтение ns


fread( (void)&#38p-&#62nr,sizeof(int),1,p-&#62fd); // Чтение nr


p-&#62ST= new item[p-&#62ns];
fread(p-&#62ST,sizeof(item),p-&#62ns,p-&#62fd); // Чтение массива описателей



// Определение size0

p-&#62size0=sizeof(int)*2 + sizeof(item) * p-&#62ns;
for (i=0,p-&#62strlnt=0; i&#60p-&#62ns; i++) // Определение длины

p-&#62strlnt += p-&#62ST[i].size; // строки таблицы

return(p);
}
//----- Чтение элемента таблицы из столбца j строки i

// функция возвращает элемент в динамической памяти

void *getrec(int i, int j, TableDef *p)
{
void *data;
int lnt; // Суммарная размерность

int k; // столбцов от 0 до j-1

if (p-&#62fd ==NULL) return NULL;
if (p-&#62ns &#60=j || p-&#62nr &#60=i) return NULL;
for (k=0,lnt=0; k&#60j; k++) lnt += p-&#62ST[k].size;
data = malloc(p-&#62ST[j].size);
fseek(p-&#62fd, p-&#62size0 + (long)p-&#62strlnt*i + lnt, 0);
//

// Смещение строк таблицы в файле +

// Размерность i полных строк +

// Сумма длин столбцов от 0 до j-1

//

fread(data,p-&#62ST[j].size,1,p-&#62fd);
return data;
}

Содержание раздела