МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
Національний університет «Львівська політехніка»
Кафедра САПР
Звіт
Про виконання лабораторної роботи №1
З курсу:
«Бази даних»
Тема: ПОСЛІДОВНИЙ МЕТОД ДОСТУПУ ДО ФАЙЛІВ НА ЗОВНІШНІХ ЗАПАМ’ЯТОВУЮЧИХ ПРИСТРОЯХ.
Мета: Розглянути органiзацiю i ведення файлiв послiдовного доступу; набути практичнi навички у програмуваннi алгоритмiв роботи з файлами послiдовного доступу.
Текст програми:
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define mainSize (sizeof (animalRecord) + 2*9)
char mainPath[256] = "dbase.pdb";
char tempPath[] = "$temp.pdb";
char searchPath[] = "$srch.pdb";
char groupPath[] = "$group.tdb";
char keyTab = 1;
FILE *dbFile = NULL, *tempFile = NULL, *groupFile = NULL;
class animalRecord
{
public:
int ID;
int Age;
char Pet[40+2];
char ownerName[40+2];
char Illness[40+2];
int price;
char notes[40+2];
int isSet;
int errorcode;
int toDo;
void readFile(FILE *CUR = NULL, int toDo = 0);
void writeToFile(FILE *CUR = NULL, int toDo = 0);
void goToKey(FILE *CUR = NULL);
animalRecord();
};
animalRecord::animalRecord()
{
ID = -1;
Age = 0;
strcpy (Pet,"-");
strcpy (Name,"-");
strcpy (Illness,"-");
price = 0;
strcpy (notes,"-");
errorcode = toDo = isSet = 0;
}
void animalRecord::writeToFile(FILE* CUR, int toDo)
{
if (CUR == NULL) return;
double cur = 0;
int i = 0;
cur = ftell(CUR);
for (i=0;i<mainSize;i++)
{
fseek (CUR,cur+i,SEEK_SET);
fprintf(CUR," ");
}
fseek(CUR,cur,SEEK_SET);
if(toDo)
fprintf(CUR,"%c\n%d\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n",keyTab,
this->ID,
this->Age,
this->Pet,
this->Name,
this->Illness,
this->price,
this->notes,
this->toDo);
else
fprintf(CUR,"%c\n%d\n%d\n%s\n%s\n%s\n%d\n%s\n",keyTab,
this->ID,
this->Age,
this->Pet,
this->Name,
this->Illness,
this->price,
this->notes);
}
void animalRecord::readFile(FILE *CUR, int toDo)
{
animalRecord buf=animalRecord();
int eofflag=0, l, read=0;
char cbuf, key=0;
buf.isSet=0;
do
{
if(feof(CUR))
{
eofflag=1;
break;
}
fscanf(CUR,"%c",&key);
}
while(key!=keyTab);
if(eofflag)
{
if(!read)
{
buf.errorcode=1;
*this = buf;
return;
}
}
//Считування запису--------------------------------------------------------------
fscanf(CUR,"\n%d\n",&buf.ID);
fscanf(CUR,"%d\n",&buf.Age);
for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++)
{buf.Pet[l]=cbuf;
fscanf(CUR,"%c",&cbuf);}
buf.Pet[l]='\0';
for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++)
{buf.Name[l]=cbuf;
fscanf(CUR,"%c",&cbuf);}
buf.Name[l]='\0';
for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++)
{buf.Illness[l]=cbuf;
fscanf(CUR,"%c",&cbuf);}
buf.Illness[l]='\0';
fscanf(CUR,"%d\n",&buf.price);
for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++)
{buf.notes[l]=cbuf;
fscanf(CUR,"%c",&cbuf);}
buf.notes[l]='\0';
if (toDo)
fscanf(CUR,"%d\n",&buf.toDo);
buf.isSet=1;
*this = buf;}
void animalRecord::goToKey(FILE *CUR)
{int i=0,a;float ad;
char key;
if((ftell(CUR))>0)
fseek(CUR,-1,SEEK_CUR);
else{return;}
do
{ad = ftell(CUR);
fscanf(CUR,"%c",&key);
fseek(CUR,ad,SEEK_SET);
if(key=='\n')
a=-2;
else
a=-1;
fseek(CUR,a,SEEK_CUR);
}while(key!=keyTab);
fseek(CUR,1,SEEK_CUR);}
//------------------------------------------------------------------------------
int reccmp(char str1[47], char str2[47], int count);
void New();
void Open();
char* SetStr(int);
animalRecord Set (animalRecord set = animalRecord () );
void Insert(animalRecord sav=animalRecord(),char* mainPath=::mainPath);
void Delete(int ID=-1);
void Modify ();
void Find ();
void Print ();
void GroupWork();
int main()
{textmode(64);
clrscr();
do
{
cout<<"\n1. Create new DataBase"<<
"\n2. Open the DB"<<
"\n3. Insert"<<
"\n4. Remove"<<
"\n5. Edit"<<
"\n6. Search..."<<
"\n7. Print all to monitor"<<
"\n8. Group work"<<
"\n9. Quit\n"<<
"Vybir: ";
switch(getch())
{case '1': clrscr();New(); break;
case '2': clrscr();Open(); break;
case '3': clrscr();Insert(); break;
case '4': clrscr();Delete(); break;
case '5': clrscr();Modify(); break;
case '6': clrscr();Find(); break;
case '7': clrscr();Print(); break;
case '8': clrscr();GroupWork();break;
case '9': clrscr();return 0;
default: clrscr();cout<<"Your choise is incorrect!\n";break;}
}while(1);}
void New()
{cout<<"Enter path: ";
cin>>mainPath;
if((dbFile = fopen (mainPath, "w+"))== NULL)
{cout<<"Can't create!\n";return;}
rewind(dbFile);
printf("%s successfully created.\n\r",mainPath);
}
void Open()
{cout<<"Enter path: ";
cin>>mainPath;
if((dbFile = fopen (mainPath, "r+"))== NULL) //Pomylka
{cout<<"Can't open!\n";return;}
cout<<"The database "<<mainPath<<" is opened...\n";}
animalRecord Set (animalRecord set)
{clrscr();
if (!set.isSet) set.ID=0;
do
{cout<<"Enter fields:\n\n";
cout<<"1. ID: "<<set.ID<<"\n";
cout<<"2. Age: "<<set.Age<<"\n";
cout<<"3. Pet Name: "<<set.Pet<<"\n";
cout<<"4. Name: "<<set.Name<<"\n";
cout<<"5. Illness: "<<set.Illness<<"\n";
cout<<"6. price: "<<set.price<<"\n";
cout<<"7. notes: "<<set.notes<<"\n\n";
cout<<"8. Ready\n";
cout<<"9. Cansel\n\n";
cout<<"Choice:\n";
switch (getch())
{case '1': cout<<"1. ID: ";cin>>set.ID;clrscr();break;
case '2': cout<<"2. Age: ";cin>>set.Age;clrscr();break;
case '3': cout<<"3. Pet: ";strcpy(set.Pet,SetStr(40));clrscr();break;
case '4': cout<<"4. Name: ";strcpy(set.Name,SetStr(40));clrscr();break;
case '5': cout<<"5. Illness: ";strcpy(set.Illness,SetStr(40));clrscr();break;
case '6': cout<<"6. Price: ";cin>>set.price;clrscr();break;
case '7': cout<<"7. Notes: ";strcpy(set.notes,SetStr(40));clrscr();break;
case '8': clrscr();set.isSet=1;return set;
case '9': clrscr();set.isSet=0;return set;
default: clrscr();cout<<"Nepravyl'nyj vybir!\n";}
}while(1);}
void Insert(animalRecord sav, char mainPath[60])
{ if (dbFile == NULL)
{cout<<"The base is not opened!\n";return;}//Pomylka
animalRecord ins = animalRecord();
if(sav.isSet)ins=sav;
else ins=Set(animalRecord());
animalRecord buf=animalRecord();
if(ins.isSet==0){printf("Couldn't insert!\n");return;}
if(ins.ID<0){printf("Couldn't insert!\n");return;}
if((tempFile=fopen(tempPath,"w"))==NULL){printf("Couldn't insert!\n");return;};
rewind(tempFile);
rewind(dbFile);
int insert=0;
do{ if(ins.toDo) buf.readFile(dbFile,1);
else buf.readFile(dbFile);
if(buf.errorcode==1)
{if(!insert)
{if(ins.toDo)
ins.writeToFile(dbFile,1);
else
ins.writeToFile(dbFile);
fclose(tempFile);
remove(tempPath);}
if(insert)
{fclose(dbFile);
fclose(tempFile);
remove(mainPath);
rename(tempPath,mainPath);
dbFile=fopen(mainPath,"r+");}
fflush(dbFile);
printf("Record %d successfully inserted.\n",ins.ID);return;}
//Kopiyuvanna doky ne znajdeno misce vstavky a takozh pisla vsyavky
if((ins.ID > buf.ID)||(insert))
if(ins.toDo)
buf.writeToFile(tempFile,1);
else
buf.writeToFile(tempFile);
//nevirne id
if(ins.ID==buf.ID){printf("Couldn't insert!\n");
fclose(tempFile);
remove(tempPath);
fclose(dbFile);
dbFile=NULL;
dbFile=fopen(mainPath,"r+");
return;}
//Vstavka
if((ins.ID < buf.ID)&&(!insert))
{
if(ins.toDo)
{
ins.writeToFile(tempFile,1);
buf.writeToFile(tempFile,1);}
else{
ins.writeToFile(tempFile);
buf.writeToFile(tempFile);}
insert=1;}
}while(1);}
void Delete(int ID)
{
if (dbFile == NULL)
{cout<<"The base isn't opened!\n";return;}//Pomylka
if(ID!=-1)goto dellab;
ID=0;
while(1)
{cout<<"1. Enter ID: "<<ID<<"\n";
cout<<"2. Remove\n";
cout<<"3. Cansel\n\nVybir:\n";
switch(getch())
{case '1': cout<<"1. Enter ID: ";cin>>ID;clrscr();break;
case '2': clrscr();goto dellab;
case '3': clrscr();return;
default: clrscr();cout<<"Incorrect choice\n";break;}
}
dellab:;
animalRecord buf=animalRecord();
if((tempFile=fopen(tempPath,"w"))==NULL){printf("Couldn't remove the record!\n");return;};
rewind(tempFile);
fclose(dbFile);
dbFile=fopen(mainPath,"r+");
// fflush(dbFile);
rewind(dbFile);
int del=0;
do{buf.readFile(dbFile);
if(buf.errorcode==1)
{if(!del)
{printf("Couldn't remove the record!\n");
fclose(tempFile);
remove(tempPath);
return;}
if(del)
{fclose(dbFile);
fclose(tempFile);
remove(mainPath);
rename(tempPath,mainPath);
dbFile=fopen(mainPath,"r+");}
printf("Record %d has been removed.\n",ID);
return;}
if((ID > buf.ID)||(del))
buf.writeToFile(tempFile);
if(ID==buf.ID){del=1;}
if( (ID < buf.ID)&&(!del) )
{printf("Couldn't remove the record!\n");
fclose(tempFile);
remove(tempPath);
return;}
}while(1);}
void Modify()
{ if (dbFile == NULL)
{cout<<"The base isn't opened!\n";return;}//Pomylka
int ID=0;
int read=0;
animalRecord buf=animalRecord(),
mod=animalRecord();
while(1)
{cout<<"1. Enter ID: "<<ID<<"\n";
cout<<"2. Edit\n";
cout<<"3. Cansel\n\nChoice:\n";
switch(getch())
{case '1': cout<<"1. Enter ID: ";cin>>ID;clrscr();break;
case '2': clrscr();goto readlab;
case '3': clrscr();return;
default: clrscr();cout<<"Incorrect choice\n";break;}}
readlab:
rewind(dbFile);
do{ buf.readFile(dbFile);
if(buf.errorcode==1)
{if(!read)
{printf("Couldn't Edit!\n");
return;}
}
if(ID==buf.ID)
{read=1;
mod=Set(buf);
Delete(mod.ID);
Insert(mod);
clrscr();
printf("Record %d is edit.\n",mod.ID);
return;}
if( (ID < buf.ID)&&(!read) )
{printf("Couldn't Edit!\n");
return;}
}while(1);}
void Find()
{FILE *T;
int fnd=0;
clrscr();
if (dbFile == NULL)
{cout<<"The base is not opened!\n";return;}//Pomylka
int tofin=0;char k;
animalRecord set = animalRecord(),buf = animalRecord();
animalRecord tmp;
T = fopen (searchPath,"w+");
cout<<"Search by:\n\n";
cout<<"1. ID "<<"\n";
cout<<"2. Age "<<"\n";
cout<<"3. Pet "<<"\n";
cout<<"4. Name "<<"\n";
cout<<"5. Illness "<<"\n";
cout<<"6. Price "<<"\n";
cout<<"7. Notes "<<"\n\n";
cout<<"8. Cansel\n\n";
cout<<"Choice:\n";
k = getch();
switch (k)
{case '1': cout<<"1. ID: ";cin>>set.ID;clrscr();break;
case '2': cout<<"2. Age: ";cin>>set.Age;clrscr();break;
case '3': cout<<"3. Pet: ";strcpy(set.Pet,SetStr(40));clrscr();break;
case '4': cout<<"4. Name: ";strcpy(set.Name,SetStr(10));clrscr();break;
case '5': cout<<"5. Illness: ";strcpy(set.Illness,SetStr(10));clrscr();break;
case '6': cout<<"6. Price: ";cin>>set.price;clrscr();break;
case '7': cout<<"7. Notes : ";strcpy(set.notes,SetStr(40));clrscr();break;
case '8': clrscr();return;
default: clrscr();cout<<"Incorrect choice!\n";return;}
tmp = set;
tofin = k - '1';
rewind(dbFile);
do{buf.readFile(dbFile);
if(buf.isSet)
switch(tofin)
{ case 0: if(tmp.ID==buf.ID)
{fnd++;
buf.writeToFile(T);}break;
case 1: if(tmp.Age==buf.Age)
{fnd++;
buf.writeToFile(T);}break;
case 2: if(!(reccmp(tmp.Pet,buf.Pet,strlen(tmp.Pet))))
{fnd++;
buf.writeToFile(T);}break;
case 3: if(!(reccmp(tmp.Name,buf.Name,strlen(tmp.Name))))
{fnd++;
buf.writeToFile(T);}break;
case 4: if(!(reccmp(tmp.Illness,buf.Illness,strlen(tmp.Illness))))
{fnd++;
buf.writeToFile(T);}break;
case 5: if(tmp.price==buf.price)
{fnd++;
buf.writeToFile(T);}break;
case 6: if(!(reccmp(tmp.notes,buf.notes,strlen(tmp.notes))))
{fnd++;
buf.writeToFile(T);}break;
}fflush(T);
}while(buf.errorcode!=1);
clrscr();
cout<<fnd<<" results\n";
rewind(T);
do
{set.readFile(T);
if(set.ID!=-1){
cout<<"ID: "<<set.ID<<"\n";
cout<<"Age: "<<set.Age<<"\n";
cout<<"Pet: "<<set.Pet<<"\n";
cout<<"Name: "<<set.Name<<"\n";
cout<<"Illness: "<<set.Illness<<"\n";
cout<<"Price: "<<set.price<<"\n";
cout<<"Notes: "<<set.notes<<"\n\n";}
}while(set.errorcode!=1);
cout<<"Press enter...";while(getch()!=13);clrscr();
fclose(T);}
void Print()
{animalRecord set;
if (dbFile == NULL)
{cout<<"The base is not opened!\n";return;}//Pomylka
rewind(dbFile);
do
{set.readFile(dbFile);
if(set.ID!=-1){
cout<<"ID: "<<set.ID<<"\n";
cout<<"Age: "<<set.Age<<"\n";
cout<<"Pet: "<<set.Pet<<"\n";
cout<<"Name: "<<set.Name<<"\n";
cout<<"Illness: "<<set.Illness<<"\n";
cout<<"Price: "<<set.price<<"\n";
cout<<"Notes: "<<set.notes<<"\n\n";}
}while(set.errorcode!=1);
cout<<"Press enter...";while(getch()!=13);clrscr();
}
char* SetStr(int count)
{char k;
int curpos=0;
char* str = (char*) malloc (count*sizeof(char));
do
{k=getche();
switch (k)
{case 8: cprintf(" %c",8);curpos--;if(curpos<0)curpos=0;str[curpos]='\0';break;//backspace
case 13: if(curpos==0){str[curpos]='-';curpos++;}str[curpos]='\0';break;
case 27: strcpy(str,"-");k=13;break;
default: str[curpos]=k; curpos++;}
if(curpos>=count-2)
{k=13;str[curpos]=k; curpos++;}
}while(k!=13);
return str;}
int reccmp(char str1[47], char str2[47], int count)
{int i=0,l1=strlen(str1),l2=strlen(str2), res=1;
for(i=0;(i<l2)&&(res);i++)
res=memcmp(str1,(str2+i),l1);
return res;}
void GroupWork()
{
if (dbFile == NULL)
{cout<<"The base is not opened!\n";return;}//Pomylka
int ex_lab1=0,ex_lab2=0,ex_lab3=0;
char kkk;
int i,a=1,b=1,sel=0;
int ID;
animalRecord buf=animalRecord(), temp=animalRecord(),
ins=animalRecord();
if( (groupFile=fopen(groupPath,"w+"))==NULL){clrscr();return;};
for(;;){
a=1;b=1;ID=0;
//while(1)
{cout<<"1. Insert\n";
cout<<"2. Edit\n";
cout<<"3. Remove\n";
cout<<"4. Do everything\n";
cout<<"5. Cansel\n";
switch(getch())
{case '1': sel=0;break;
case '2': sel=1;break;
case '3': sel=2;break;
case '4': sel=3;break;
case '5': sel=4;break;
default: clrscr();cout<<"Incorrect choice\n";break;}}
switch(sel)
{case 0: temp=Set();
if(temp.isSet==0){break;}
rewind(dbFile);
do
{buf.readFile(dbFile,0);}
while((temp.ID!=buf.ID)&&(buf.errorcode!=1));
if((temp.ID==buf.ID)&&(buf.isSet==1))
{break;}
fclose(dbFile);
fclose(groupFile);
if((dbFile=fopen(groupPath,"r+"))==NULL){ex_lab1=1;break;}
rewind(dbFile);
rewind(dbFile);
buf=temp;
buf.toDo=1;
Insert(buf,groupPath);
printf("(to the group file: %s)\n",groupPath);
fclose(dbFile);
if((groupFile=fopen(groupPath,"r+"))==NULL){ex_lab1=1;break;}
if((dbFile=fopen(mainPath,"r+"))==NULL){ex_lab1=1;break;}
break;
case 1: sel=0;clrscr();ex_lab1=0;
for(;!ex_lab1;){
a=1;b=1;
kkk='1';
while(kkk=='1')
{cout<<"1. Enter ID: "<<ID<<"\n";
cout<<"2. Edit\n";
cout<<"3. Cancel\n\nVybir:\n";
switch(kkk=getch())
{case '1': cout<<"1. Enter ID: ";cin>>ID;clrscr();break;
case '2': clrscr();
rewind(dbFile);
do
{buf.readFile(dbFile,0);}
while((ID!=buf.ID)&&(buf.errorcode!=1));
if((ID!=buf.ID)||(buf.isSet!=1)){break;}fclose(dbFile); fclose(groupFile);
if((dbFile=fopen(groupPath,"r+"))==NULL){ex_lab1=1;break;}
rewind(dbFile);