Методические указания для выполнения лабораторных работ и курсовой работы содержание

Вид материалаМетодические указания

Содержание


8 Лабораторная работа № 7. Файловые структуры
2.Цель работы
3.Список заданий на выполнение работы
Подобный материал:
1   2   3   4   5   6   7   8   9   ...   12

8 Лабораторная работа № 7. Файловые структуры



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


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

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

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

2.Цель работы


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

Машинная реализация этих структур планируется на языке Турбо Паскаль или С++.


3.Список заданий на выполнение работы


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

1.Разработать программу автоматического включения, выключения и поиска

элемента файла в алфавитном порядке.

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

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

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

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

6.Разработать программу автоматического включения, выключения и поиска пачки элементов файла по значению приоритета (если не обработаны все элементы с более высоким приоритетом, элементы с более низким приоритетом не обрабатываются).

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

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

9.Разработать программу обмена элементов между двумя файлами по значению приоритета.

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

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

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

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

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

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

16.Разработать программу записи (и восстановления)в файл стековой структуры.

17.Разработать программу записи (и восстановления)в файл очереди.

18.Разработать программу записи (и восстановления) в файл структуры, построенной на связанном списке.

19.Разработать программу записи (и восстановления) в файл графовидной структуры.

20.Пусть файл состоит из записей по 80 байт. Разработать программу перехода к следующей или предыдущей записи файла по нажатию соответствующих клавиш.

21.Разработать программу доступа к файлу по функции хэширования.


ПРИЛОЖЕНИЕ 1

Пример программы с использованием файлов на Турбо Паскале


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

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

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

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

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


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


program dann;

uses crt;

type

xo=(music,sport,fiction,painting);

persona =record {ЛИЧНОСТЬ}

famili : string[15];

name : string[10];

year:1900..2000;

xobby: xo;

end;

p=array[1..60] of persona;

var

ff,f:file of p;

kod:byte;

{*************************************************************

отображение данных о личности

***************************************************************}

PROCEDURE oto1(per:persona);


var

i,m:integer;

begin

with per do

begin

write(famili,' ');

write(name,' ');

write(year);

write(' хобби : ');

case xobby of

sport: write(' спорт ');

music :write(' музыка ');

fiction:write (' литература ');

painting:write(' живопись ') ;

end;

writeln;

end;

end;

{*****************************************************************

искать место по году и записать личность в файл

*****************************************************************}

procedure find( per:persona);

var

d,f:file of persona;

a:persona;

c,l,q:byte;

xr:array[1..30]of persona;


begin

assign(f,'li.');

reset(f);

repeat

if NOT(EOF(F)) then

read(f,a);

until (a.year > per.year)or eof(f) ;

c:=filepos(f);

if (c<>0)and(a.year > per.year) then seek(f,c-1);

if not(eof(f))then

begin

q:=0;

while not(eof(f)) do

begin

q:=q+1;

read(f,xr[q]);

end;

seek(f,c-1);

with per do

write(f,per);

for l:=1 to q do

write(f,xr[l]);

end

else

begin

with per do

begin

write(f,per);

end;

end;

close(f);

end;


{*********************************************************

ввод данных о личности

*********************************************************}

procedure inppers;

var

i,k,n:integer;

per:p;

ind:boolean;

by:char;


begin

n:=0;

repeat

n:=n+1;

with per[n] do

begin

write(' введите фамилию : ');

repeat

readln(famili);

until famili <>'';

write(' введите имя : ');

readLN(name);

write(' введите год рождения(1900..2000) : ');

readln (year);

write(' введите хобби : ');

write(' (p-живопись;s-спорт;f-литература;m-музыка )');

repeat

readln(by);

until by in['s','m','f','p'];

case by of

's' : xobby:=sport;

'm' : xobby:=music;

'f' : xobby:=fiction;

'p' : xobby:= painting;

end;

writeln('ввод окончен y/n');

end;

until readkey='y';

for k:=n downto 1 do

find(per[k]);

end;


{******************************************************************

искать по увлечению

*****************************************************************}

procedure isk;

var ch:char;

f:file of persona;

a:persona;

l, n:byte;

chh:xo;


begin

clrscr;

assign(f,'li.');

reset(f);

writeln('введите увлечение :');

repeat

read(ch);

until ch in['p','P','S','s','f','F','M','m'];

case ch of

's' : chh:=sport;

'm' : chh:=music;

'f' : chh:=fiction;

'p' : chh:= painting;

end;

l:=1;

while not(eof(f)) do

begin

read(f,a);

if a.xobby =chh

then oto1(a)

else

begin

clrscr;

if eof(f) then

writeln('персоны с такими данными нет');

end;

end;

close(f);

end;

{*********************************************************

удалить по Фам.

**********************************************************}

procedure era;

var

f:file of persona;

per:p;

i:integer;

fam,ot :string[15];

ame:string[10];

begin

clrscr;

writeln('фамилия');

repeat

readln(fam);

until fam<>'';

writeln('имя');

readln(ame);

i:=0;

assign(f,'li');

reset(f);

while not(eof(f)) do

begin

i:=i+1;

read(f,per[i]);

if per[i].famili= fam then

if per[i].name= ame then

while not(eof(f)) do

begin

i:=i+1;

read(f,per[i]);

seek(f,filepos(f)-2);

write(f,per[i]);

seek(f,filepos(f)+3);

end;

end;

seek(f,filesize(f)-1);

truncate(f);

close(f);

end;

{***********************************************************

показать файл персон

************************************************************}

procedure demo;

var

f:file of persona;

per:p;

i:integer;

begin


i:=0;

assign(f,'li');

reset(f);

while not(eof(f)) do

begin

i:=i+1;

read(f,per[i]);

oto1(per[i]);

end;

close(f);

end;

{**** программа ******}

BEGIN

clrscr;

assign(ff,'li.');

rewrite(ff);

close(ff);

repeat

writeln('Введите требуемую операцию :');

writeln('искать - 1');

writeln('удалять - 2');

writeln('вводить - 3');

writeln('демонстрация - 4');

writeln('выход - 5');

repeat

read(kod);

until kod in[1..5];

case kod of

1: begin

clrscr;

isk; {искать}

write('выход - w');

repeat

until readkey='w';

end;

2: begin

era; {удалять}

clrscr;

demo;

write('выход - w');

repeat

until readkey='w';

end;

3: inppers; {вводить}

4: begin

demo; {демонстрировать}

write('выход - w');

repeat

until readkey='w';

end;

5: halt;

end;

clrscr;

until 11<>11;

END.


ПРИЛОЖЕНИЕ 2

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

Все варианты заданий рассчитаны на файлы прямого доступа. В С++ создание формативного файла затруднено и поэтому целесообразней непосредственно работать с указателем на требуемую позицию файла. В этом случае можно создать более гибкую структуру файла, однако следует проявлять внимательность при работе с указателем, так как все проблемы, связанные с вычислением позиции указателя, при таком подходе приходится решать непосредственно программисту. При организации работы с файлами на С++ следует помнить о некоторых тонкостях, связанных с типом доступа открываемых файлов. Отметим некоторые из них. Тип доступа определяется при его открытии и имеет вид "s1 s2", где s1-символ или символ с "+",определяет операцию, а s2- текстовой (t) или двоичный (b) .

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

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

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

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

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

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

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

Полезно запомнить, что автоматическое выравнивание по полям записей не происходит. Например, если на строковую переменную отводится 20 байт, а фактически она занимает 10, то следующая запись пойдет с 11-ого байта, т. е. первого свободного. Это может создать трудности при вычислении требуемой позиции при чтении. Поэтому для успешной работы пользователь должен сам продумать процедуру выравнивания полей (см. текст программы).

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

Ниже приведен адекватный текст программы на С++ для задачи из Приложения 1.

#include

#include

#include

#include

#include

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
yer)&&(i
{ 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
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
{ 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
{ 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
{ 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
{ // и сдвиг всех последующих записей влево

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");

}