Добавил:
Факультет ИКСС, группа ИКВТ-61 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
26
Добавлен:
20.02.2019
Размер:
23.21 Кб
Скачать

ПРИЛОЖЕНИЕ 1 Файловые структуры

1.Общие понятия

Файл-это поименованное пространство на томе. Он предназначен для долго временного упорядоченного хранения информации.

Файлы подразделяются на последовательные файлы и на файлы прямого доступа.

В первых информация просматривается последовательно и поиск нужной порции

информации производится каждый раз начиная с начала файла. В файлах прямого

доступа по адресу сразу находится требуемая порция информации. Тип файла

определяет и тип организации работы с файлами, который существенно отличается

один от другого.

Следует отметить,что в языке Паскаль возможно создание формативного файла, что упрощает

разработку процедуры прямого доступа к файлу, но накладывает ограничения

на структуру файла. В С++ создание формативного файла затруднено и поэтому

целесообразней непосредственно работать с указателем на требуемую позицию

файла. В этом случае можно создать более гибкую структуру файла, однако

следует проявлять большую внимательность при работе с указателем, так

как все проблемы, связанные с вычислением позиции указателя, при таком

подходе приходится решать непосредственно программисту. При организации

работы с файлами на С++ следует помнить о некоторых тонкостях, связанных

с типом доступа открываемых файлов. Отметим некоторые из них. Тип доступа

определяется при его открытии и имеет вид "s1 s2", где s1-символ или сим-

вол с "+",определяет операцию, а s2- текстовой (t) или двоичный (b) .

Ниже приведены значения, которые может принимать s1:

"r"-поток открывается для чтения;

"w"-открывается пустой поток для записи;

"a"- поток открывается для записи в конец;

"r+"- поток для чтения и записи ( поток должен существовать);

"w+"-открывается пустой поток для чтения и записи;

"a+"- поток окрывается для чтения и записи в конец файла.

Полезно запомнить, что автоматическое выравнивание по полям записей не

происходит. Например, если на строковую переменную отводится 20 байт, а

фактически она занимает 10, то следующая запись пойдет с 11-ого байта,

т. е. первого свободного. Это может создать трудности при вычислении

требуемой позиции при чтении. Поэтому для успешной работы пользователь

должен сам продумать процедуру выравнивания полей (см. Приложение 2).

Примечание: Наиболее оптимально все вопросы, связанные с файловыми

операциями, можно решить используя язык ассемблер.

Пример программы с использованием файлов на C++

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

При этом следующие операции должны быть обязательными:

1)Ввод данных в файл в поряде возрастания года рождения;

2)Отображение данных;

3)Поиск данных по увлечению(хобби);

4)Удаление данных с заданными фамилией и именем.

В этом примере приведен на языке С++ текст программы для задачи,

приведенной в Приложении 1.

#include <alloc.h>

#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

const int be=2;/* Число байт, отводимых для фиксирования количества записей*/

typedef

struct pr{

char fam[10];

char nam[10];

char xob[2];

int yer;

};

FILE *fl_ptr;

void sort(FILE *f_p,struct pr *pt,struct pr *pt1);

void inpfil(struct pr *p);

void out_oll(FILE *f_p,struct pr *pt);

void ch_xob(FILE *f_p,struct pr *pt);

void del_fam(FILE *f_p,struct pr *pt);

void main()

{

struct pr *p,*p1;

int i,n;

char ch,chh,coh,chc,che,ch_men;

do {

printf("Если дополнение в файл, то введите \"y\": иначе-любой символ\n");

chh=tolower(getch());

n=sizeof(struct pr);

i=1;

p=(struct pr*)malloc(sizeof(struct pr));

p1=(struct pr*)malloc(sizeof(struct pr));

coh='*';

if(chh!='y')

{ /* Открытие пустого файла */

if((fl_ptr=fopen("aaa.txt","w+"))==NULL)

{ fprintf(stderr,"Ошибка открытия файла\"aaa.txt\"\n");

return;

}

/* Ввод */

inpfil(p); /* в файл */

fseek(fl_ptr,be,SEEK_SET); /* первого */

fprintf(fl_ptr,"%s %s %s %d",p->fam,p->nam,p->xob,p->yer);/*эл-та */

fseek(fl_ptr,0L,SEEK_SET); /* Запись в первые позиции файла */

fprintf(fl_ptr,"%d",i); /* количества вводимых записей */

fseek(fl_ptr,n+be-1,SEEK_SET); /* Выравнивание по длине */

fprintf(fl_ptr,"%c",coh); /* вводимой записи */

}

else { /* Открытие существующего файла */

if((fl_ptr=fopen("aaa.txt","r+"))==NULL)

{ fprintf(stderr,"Ошибка открытия файла\"aaa.txt\"\n");

return;

}

}

do { /* Заполнение записей в цикле */

i++;

inpfil(p);

sort(fl_ptr,p1,p); /* Включение новой записи в подходящее место */

printf("Если хотите закончить ввод, нажмите клавишу \"y\":\n");

ch=tolower(getch());

} while(ch!='y');

do{ /* Меню операций */

printf("Выберите операцию: удаление записи - \"d\"\n");

printf(" выбор по увлечению-\"c\";\n");

printf(" полное чтение файла-\"r\" \n");

chc=tolower(getch());

switch(chc){

case 'r': out_oll(fl_ptr,p); break;

case 'c': ch_xob(fl_ptr,p); break;

case 'd': del_fam(fl_ptr,p); break;

}

printf("Для выхода из меню операций нажмите клавишу-\"m\";\n");

ch_men=tolower(getch());

}while(ch_men!='m');

fclose(fl_ptr);

printf("Для окончания работы нажмите клавишу-\"e\";\n");

che=tolower(getch());

} while(che!='e');

}

/* *************************************************************************

ВВод данных в запись

********************************************************************* */

void inpfil(struct pr *p)

{

clrscr();

printf("ВВедите фамилию:\n");

scanf("%s",p->fam);

printf("ВВедите имя:\n");

scanf("%s",p->nam);

printf("ВВедите хобби:м-музыка,с-спорт,л-литература,ш-шахматы\n");

scanf("%s",p->xob);

printf("ВВедите год рождения:\n");

scanf("%d",&p->yer);

printf("%s %s %d %s\n",p->fam,p->nam,p->yer,p->xob);

}

/* *******************************************************************

Эта функция включает новую запись в файл в подходящее место,

используя сортировку методом включения

********************************************************************** */

void sort(FILE *f_p,struct pr *pt,struct pr *pt1)

{ int x,i,n,j,cod,rol,y; char ch;

ch='*';

n=sizeof(struct pr);

fseek(f_p,0L,SEEK_SET); /*установка указателя в начало файла */

fscanf(f_p,"%d",&cod); /*считывание из файла кол-ва записей */

rol=n*(cod-1)+be; /*установка указателя */

fseek(f_p,rol,SEEK_SET); /* на последнюю запись */

fscanf(f_p,"%s %s %s %d ",pt->fam,pt->nam,pt->xob,&pt->yer);

i=0;

while((pt1->yer<pt->yer)&&(i<cod)) /* поиск подходящего места */

{ i++;

rol=n*(cod-i)+be; /* установка указателя */

fseek(f_p,rol,SEEK_SET); /* на текущую запись */

fscanf(f_p,"%s %s %s %d ",pt->fam,pt->nam,pt->xob,&pt->yer);

rol=n*(cod-i+1)+be; /* установка указателя */

fseek(f_p,rol,SEEK_SET); /* на последующую запись */

fprintf(f_p,"%s %s %s %d ",pt->fam,pt->nam,pt->xob,pt->yer);

rol=rol+n-1; /* выравнивание */

fseek(f_p,rol,SEEK_SET); /* полей */

fprintf(f_p,"%c",ch); /* записей */

if(i<cod) { rol=n*(cod-i-1)+be;

fseek(f_p,rol,SEEK_SET);

fscanf(f_p,"%s %s %s %d",pt->fam,pt->nam,pt->xob,&pt->yer);

}

}

rol=(cod-i)*n+be; /* включение новой записи */

fseek(f_p,rol,SEEK_SET); /* в подходящее */

fprintf(f_p,"%s %s %s %d",pt1->fam,pt1->nam,pt1->xob,pt1->yer); /* место */

fseek(f_p,0L,SEEK_SET);

cod=cod+1; /* наращивание числа записей */

fseek(f_p,0L,SEEK_SET); /* включением */

fprintf(f_p,"%d",cod); /* новой записи */

rol=cod*n+be-1; /* выравнивание */

fseek(f_p,rol,SEEK_SET); /* полей */

fprintf(f_p,"%c",ch); /* новой записи */

}

/* *****************************************************************

Вывод содержимого всех записей

************************************************************** */

void out_oll(FILE *f_p,struct pr *pt)

{ int rol,i,cod;

fseek(f_p,0L,SEEK_SET); /* извлечение из файла */

fscanf(f_p,"%d",&cod); /* количества записей */

printf(" Содержимое файла: \n");

for(i=0; i<cod;i++) /* просмотр в цикле очередных записей */

{ rol=sizeof(struct pr)*i+be; /* позиционирование */

fseek(f_p,rol,SEEK_SET); /* указателя */

fscanf(f_p,"%s %s %s %d",pt->fam,pt->nam,pt->xob,&pt->yer);

printf(" %s %s %d",pt->fam,pt->nam,pt->yer);

switch(pt->xob[0])

{

case 'м': printf(" музыка \n"); break;

case 'с': printf(" спорт \n"); break;

case 'л': printf(" литература \n"); break;

case 'ш': printf(" шахматы \n"); break;

}

}

}

/* ***************************************************************

Поиск по увлечениям

****************************************************************** */

void ch_xob(FILE *f_p,struct pr *pt)

{

int rol,i,cod;

char ch;

printf("ВВедите хобби:м-музыка,с-спорт,л-литература,ш-шахматы\n");

ch=tolower(getch());

fseek(f_p,0L,SEEK_SET); /* извлечение из файла */

fscanf(f_p,"%d",&cod); /* количества записей */

printf(" Персоны с одинаковым увлечением: \n");

for(i=0; i<cod;i++) /* Поиск персон с одинаковым увлечением */

{ rol=sizeof(struct pr)*i+be;

fseek(f_p,rol,SEEK_SET);

fscanf(f_p,"%s %s %s %d",pt->fam,pt->nam,pt->xob,&pt->yer);

if(pt->xob[0]==ch){

printf(" %s %s %d",pt->fam,pt->nam,pt->yer);

switch(pt->xob[0])

{

case 'м': printf(" музыка "); break;

case 'с': printf(" спорт "); break;

case 'л': printf(" литература "); break;

case 'ш': printf(" шахматы "); break;

}

printf("\n");

}

}

}

/* ***************************************************************

Поиск и удаление по заданной фамилии

****************************************************************** */

void del_fam(FILE *f_p,struct pr *pt)

{

int rol,i,cod,n,metka;

char ch[10],chh;

chh='*';

fseek(f_p,0L,SEEK_SET); /* извлечение из файла */

fscanf(f_p,"%d",&cod); /* количества записей */

n=sizeof(struct pr);

metka=0;

printf("ВВедите фамилию: \n");

scanf("%s",ch);

for(i=0; i<cod;i++) /* поиск требуемого элемента */

{ rol=n*i+be; /* установка */

fseek(f_p,rol,SEEK_SET); /* текущего */

fscanf(f_p,"%s",pt->fam); /* указателя */

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

if(strcmp(ch,pt->fam)==0) metka=1;

if((metka==1)&&(i<cod)) /* удаление найденной записи */

{ /* и сдвиг всех последующих записей влево */

rol=rol+n; /* установка последущего */

fseek(f_p,rol,SEEK_SET); /* указателя */

fscanf(f_p,"%s %s %s %d",pt->fam,pt->nam,pt->xob,&pt->yer);

rol=rol-n; /* возврвщение к текущему */

fseek(f_p,rol,SEEK_SET); /* указателю */

fprintf(f_p,"%s %s %s %d",pt->fam,pt->nam,pt->xob,pt->yer);

rol=rol+n-1; /* выравнивание */

fseek(f_p,rol,SEEK_SET); /* записей */

fprintf(f_p,"%c",chh); /* по полям */

}

}

/* корректировка числа записей с учетом удаленной */

if(metka==1){

cod--;

fseek(f_p,0L,SEEK_SET);

fprintf(f_p,"%d",cod);

}

if(metka==0) printf(" Записи с такой фамилией нет \n");

}

Соседние файлы в папке _2017-ЛАБОРАТОРНЫЕ РАБОТЫ 2 КУРС