МIНIСТЕРСТВО ОСВIТИ І НАУКИ УКРАЇНИ
Національний університет «Львiвська полiтехнiка»
Звіт
до лабораторної роботи №2
на тему
«Прямий метод доступу до файлів на зовнішніх запам’ятовуючих пристроях»
з курсу "Організація баз даних і знань "
Львів 2016
Тема
Прямий метод доступу до файлів на зовнішніх запам’ятовуючих пристроях.
Мета роботи
Розглянути органiзацiю i ведення файлiв прямого доступу; набути практичнi навички у програмуваннi алгоритмiв доступу хешуванням.
Завдання:
1. Написати програму методу прогресуючого переповнення, яка реалiзує такi функцiї:
1. Друк бази даних.
2. Зчитування запису.
3. Введення запису.
4. Видалення запису.
5. Модифiкацiя запису.
6. Вихід.
2. Написати програму методу зв'язаних блокiв, яка реалiзує такi функцiї:
1. Друк бази даних.
2. Зчитування запису.
3. Введення запису.
4. Видалення запису.
5. Модифiкацiя запису.
6. Вихід.
Індивідуальне завдання:
Магазин будівельних матеріалів
Текст програми:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include <iostream.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
#define BLOCKS 10
#define BLOCK_ROWS 6
#pragma argsused
// global vars
FILE *db;
char file_name[100];
struct data{
int id, Number, securityDet, lifetimeDet, salesDet;
int priceDet;
char company[20], nameDet[20], categoryDet[20], returnDet[20];
};
struct data parser(char *s);
int hash(int id){
return (id % BLOCKS)-1;
}
void read_row(char *buf){
int i=0 ;
for (i = 0;i<255&&!feof(db); i++){ //??????? ?????
fscanf(db,"%c",&buf[i]);
buf[i+1]='\0';
if(buf[i]=='\n'){
buf[i]='\0';
break;
}
}
}
void write_row(FILE *f, struct data row){
fprintf(f,"%i|%i|%i|%i|%i|",row.id,row.Number,row.priceDet,row.securityDet,row.lifetimeDet);
fprintf(f,"%i|%s|%s|%s|%s|\n",row.salesDet,row.company,row.nameDet,row.categoryDet,row.returnDet);
}
void block_read(struct data block[]){
int i=0;
char buf[255];
for (i = 0; i < BLOCKS; i++) {
block[i].id=0;
}
for (i = 0; i < BLOCK_ROWS && !feof(db); i++) {
read_row(buf);
block[i]=parser(buf);
}
}
void block_write(FILE *f, struct data *block){
int i=0;
for (i = 0; i < BLOCK_ROWS; i++) {
if(block[i].id==0){
fprintf(f,"0||||||||||\n");
}else{
write_row(f,block[i]);
}
}
}
int db_conect(void){
int i;
char c;
system("pause");
for (i=0;i<sizeof(file_name);i++){file_name[i]='\0';}
printf("Database adress: ");
fflush(stdin);
/**
file_name[0]='f';
file_name[1]='1';
file_name[2]='.';
file_name[3]='d';
file_name[4]='b';
**/
scanf("%s",&file_name);
db=fopen(file_name,"r");
if(db==0){
printf("\ndatabase not find!\n 1- insert new database adress\n 2- exit\n");
c=getchar();
if(c=='1')db_conect();else
if(c!='1')return 0;
}
return 1;
}
struct data parser(char *s){
char b[255];
struct data row;
int i=0, tmp=0,y,bi=0;
row.id=0;
while(s[i]!='\0'&&s[i]!='\n'){
if(s[i]=='|'){
switch (tmp) {
case 0:{row.id=atoi(b);break;}
case 1:{row.Number=atoi(b);break;}
case 2:{row.priceDet=atoi(b);break;}
case 3:{row.securityDet=atoi(b);break;}
case 4:{row.lifetimeDet=atoi(b);break;}
case 5:{row.salesDet=atoi(b);break;}
case 6:{for(y=0;y<sizeof(row.company);y++)row.company[y]=b[y];break;}
case 7:{for(y=0;y<sizeof(row.nameDet);y++)row.nameDet[y]=b[y];break;}
case 8:{for(y=0;y<sizeof(row.categoryDet);y++)row.categoryDet[y]=b[y];break;}
case 9:{for(y=0;y<sizeof(row.returnDet);y++)row.returnDet[y]=b[y];break;}
default:break;
}
for (bi = 0; bi < sizeof(b); bi++)b[bi]='\0';
bi=0;
tmp++;
}else{
b[bi]=s[i];
bi++;
}
i++;
}
return row;
}
void print_shapka(void){
//printf("ID | Remains |Security | Price | Lifetime | Sales | Company | NameDet | Category | ReturnDet\n");
printf("***Output***\n");
}
void print_row(struct data row){
//printf("%3i|%8i|%8i|%8i|%5i|%4i|%6s|%6s|%9s|%7s\n",row.id,row.Number,row.securityDet,row.priceDet,row.lifetimeDet,row.salesDet,row.company,row.nameDet,row.categoryDet,row.returnDet);
// printf("ID\n%3i \n",row.id);
// printf("Remains\n%8i \n",row.Number);
// printf("Security\n%8i \n",row.securityDet);
// printf("Price\n%8i \n",row.priceDet);
// printf("Weight\n%5i \n",row.lifetimeDet);
// printf("Sales\n%4i \n",row.salesDet);
// printf("Company\n%6s \n",row.company);
// printf("Name\n%6s \n",row.nameDet);
// printf("Category\n%9s \n",row.categoryDet);
// printf("Available\n%7s \n",row.returnDet);
printf("\n----------------------------------\n");
printf("ID = %d\n",row.id);
printf("Number = %d\n",row.Number);
printf("Security = %d\n",row.securityDet);
printf("Price = %d\n",row.priceDet);
printf("Weight = %d\n",row.lifetimeDet);
printf("Sales = %d\n",row.salesDet);
printf("Company = %s\n",row.company);
printf("Name = %s\n",row.nameDet);
printf("Category = %s\n",row.categoryDet);
printf("Available = %s\n ",row.returnDet);
}
void showAll(void){
struct data row;
char buf[255],b[255];
int i,j,tmp,bi,y;
system("pause");
print_shapka();
for (i = 0; !feof(db); i++) {
//for (j = 0; j < sizeof(buf); j++)buf[j]='\0';
for (j = 0;!feof(db)&&j<255; j++){ //??????? ?????
fscanf(db,"%c",&buf[j]);
buf[j+1]='\0';
if(buf[j]=='\n'){
buf[j]='\0';
break;
}
}
row=parser(buf);
if(row.id>0)print_row(row);
row.id=0;
}
fseek(db,0,0);
getch();
}
void InsertRow(void){
FILE *tmp;
struct data row,temp,block[BLOCKS];
int i,bi,h;
int insert=0;
char buf[255];
system("pause");
printf("********[Insert in %10s]********\n",&file_name);
fflush(stdin);
printf("* ID(int) = "); scanf("%i",&row.id);
fflush(stdin);
printf("* Number(int) = "); scanf("%i",&row.Number);
fflush(stdin);
printf("* SecurityDet(int) = "); scanf("%i",&row.securityDet);
fflush(stdin);
printf("* Price(int) = "); scanf("%i",&row.priceDet);
fflush(stdin);
printf("* Weight(int) = "); scanf("%i",&row.lifetimeDet);
fflush(stdin);
printf("* SalesDet(int) = "); scanf("%i",&row.salesDet);
fflush(stdin);
printf("* Company(char) = "); scanf("%s",&row.company);
fflush(stdin);
printf("* Name(char) = "); scanf("%s",&row.nameDet);
fflush(stdin);
printf("* Category(char) = "); scanf("%s",&row.categoryDet);
fflush(stdin);
printf("*Available(char) = "); scanf("%s",&row.returnDet);
h=hash(row.id);
fseek(db,0,0);
tmp=fopen("tmp.txt","w");
for (bi = 0; bi < BLOCKS && !feof(db); bi++) {
block_read(block);
if (bi==h) {
// ???????? ? ????
for (i = 0; i < BLOCK_ROWS; i++) {
if(block[i].id==row.id){
insert=1;
break;
}
if(block[i].id==0){
block[i]=row;
insert=1;
break;
}
}
}
block_write(tmp,block);
}
if(insert==0){
while(bi<=hash(row.id)){
block_read(block);//block clear
if(bi==h){
block[0]=row;
insert=1;
}
block_write(tmp,block);
bi++;
}
}
//???? ???????????? ????
for (bi = bi; bi < BLOCKS; bi++) {
block_read(block);
block_write(tmp,block);
}
//??????????? ??? ????
while(!feof(db)){
read_row(buf);
temp=parser(buf);
if(temp.id!=0)write_row(tmp,temp);
}
if(insert==0){write_row(tmp,row); }
fclose(tmp);
fclose(db);
remove(file_name);
rename("tmp.txt",file_name);
db=fopen(file_name,"r");
printf("done! press any kay to continue");
getch();
}
int rivne(char *a, char *b){
int i;
for (i = 0; i >=0; i++) {
if(a[i]!=b[i])return 0;
if(a[i]=='\0'|b[i]=='\0')break;
}
return 1;
}
int quest(void){
char k;
while(1>0){
fflush(stdin);
k=getchar();
if(k=='Y'|k=='y'){
return 1;
}else if(k=='N'|k=='n'){
return 0;
}
}
}
void Delete(void){
FILE *tmp;
struct data row,temp,block[BLOCKS],dop[10];
int i,bi,h,c,dopc=0,del_dop=0;
char buf[255];
system("pause");
fseek(db,0,0);
tmp=fopen("tmp.txt","w");
printf("Insert ID for delete row\n ID = ");
fflush(stdin);
scanf("%i",&c);
h=hash(c);
// ??????? ???. ???? ? ????"??
for (i = 0; i < BLOCKS && !feof(db); i++) {
block_read(block);
}
for (dopc = 0; !feof(db); dopc++) {
read_row(buf);
dop[dopc]=parser(buf);
}
dopc--;
fseek(db,0,0);
for (bi = 0; bi < BLOCKS && !feof(db); bi++) {
block_read(block);
if (bi==h) {
// ????????
for (i = 0; i < BLOCK_ROWS; i++) {
if(block[i].id==c){
block[i].id=0;
//????????? ? ???.
for (c=0; c < dopc; c++) {
if(hash(dop[c].id)==h){
block[i]=dop[c];
del_dop=dop[c].id;
break;
}
}
break;
}
}
}
block_write(tmp,block);
}
//??????????? ??? ????
while(!feof(db)){
read_row(buf);
temp=parser(buf);
if(temp.id!=0&&temp.id!=c&&temp.id!=del_dop)write_row(tmp,temp);
}
fclose(tmp);
fclose(db);
remove(file_name);
rename("tmp.txt",file_name);
db=fopen(file_name,"r");
printf("done! press any kay to continue");
getch();
}
int Update(){
FILE *tmp;
struct data row,temp,block[BLOCKS];
int i,bi,h,c;
char buf[255];
system("pause");
fseek(db,0,0);
tmp=fopen("tmp.txt","w");
printf("Insert ID for update row\n ID = ");
fflush(stdin);
scanf("%i",&c);
h=hash(c);
row.id=0;
for (bi = 0; bi < BLOCKS && !feof(db); bi++) {
block_read(block);
for (i = 0; i < BLOCK_ROWS; i++) {
if(block[i].id==c){
row=block[i];
break;
}
}
if(row.id!=0&&row.id==c){
print_shapka();
print_row(row);
fflush(stdin);
printf("Company = %s UPDATE ? Yes/No: ",row.company);
if(quest()){
printf("\tCompany(char) = ");
scanf("%s",&row.company);
}
fflush(stdin);
printf("Name = %s UPDATE ? Yes/No: ",row.nameDet);
if(quest()){
printf("\tNameDet(char) = ");
scanf("%s",&row.nameDet);
}
fflush(stdin);
printf("Category = %s UPDATE ? Yes/No: ",row.categoryDet);
if(quest()){
printf("\tCategory(char) = ");
scanf("%s",&row.categoryDet);
}
fflush(stdin);
printf("Available = %s UPDATE ? Yes/No: ",row.returnDet);
if(quest()){
printf("\tAvailable(char) = ");
scanf("%s",&row.returnDet);
}
fflush(stdin);
printf("Remains = %i UPDATE ? Yes/No: ",row.Number);
if(quest()){
printf("\tNumber(int) = ");
scanf("%i",&row.Number);
}
fflush(stdin);
printf("Price = %i UPDATE ? Yes/No: ",row.priceDet);
if(quest()){
printf("\tPriceDet(int) = ");
scanf("%i",&row.priceDet);
}
fflush(stdin);
printf("Security = %i UPDATE ? Yes/No: ",row.securityDet);
if(quest()){
printf("\tSecurityDet(int) = ");
scanf("%i",&row.securityDet);
}
fflush(stdin);
printf("Weight = %i UPDATE ? Yes/No: ",row.lifetimeDet);
if(quest()){
printf("\Weight(int) = ");
scanf("%i",&row.lifetimeDet);
}
fflush(stdin);
printf("Sales = %i UPDATE ? Yes/No: ",row.salesDet);
if(quest()){
printf("\tSalesDet(int) = ");
scanf("%i",&row.salesDet);
}
block[i]=row;
row.id=0;
}
block_write(tmp,block);
}
//??????????? ??? ????
while(!feof(db)){
read_row(buf);
temp=parser(buf);
if(temp.id!=0)write_row(tmp,temp);
}
fclose(tmp);
fclose(db);
remove(file_name);
rename("tmp.txt",file_name);
db=fopen(file_name,"r");
printf("done! press any kay to continue");
getch();
return 0;
}
int Search(){
struct data row,ss;
char buf[255],b[255];
int i,j,tmp,bi,y,c;
system("pause");
printf("Choose KEY:\n");
printf("1 - ID\n");
printf("2 - Remains\n");
printf("3 - Security\n");
printf("4 - Price\n");
printf("5 - Weight\n");
printf("6 - Sales\n");
printf("7 - Company\n");
printf("8 - Name\n");
printf("9 - Categoryn");
printf("10 - Available\n");
scanf("%i",&c);
fflush(stdin);
switch (c) {
case 1:{printf("ID = ");scanf("%i",&ss.id);break;}
case 2:{printf("Remains = ");scanf("%i",&ss.Number);break;}
case 3:{printf("Security = ");scanf("%i",&ss.securityDet);break;}
case 4:{printf("Price = ");scanf("%i",&ss.priceDet);break;}
case 5:{printf("Weight = ");scanf("%i",&ss.lifetimeDet);break;}
case 6:{printf("SalesDet = ");scanf("%i",&ss.salesDet);break;}
case 7:{printf("Company = ");scanf("%s",&ss.company);break;}
case 8:{printf("NameDet = ");scanf("%s",&ss.nameDet);break;}
case 9:{printf("Category = ");scanf("%s",&ss.categoryDet);break;}
case 10:{printf("Available = ");scanf("%s",&ss.returnDet);break;}
default: return 0;
}
//c++;
print_shapka();
for (i = 0; !feof(db); i++) {
//for (j = 0; j < sizeof(buf); j++)buf[j]='\0';
for (j = 0;!feof(db)&&j<255; j++){ //??????? ?????
fscanf(db,"%c",&buf[j]);
buf[j+1]='\0';
if(buf[j]=='\n'){
buf[j]='\0';
break;
}
}
row=parser(buf);
if(row.id>0){
if((c==1&&row.id==ss.id) | (c==2&&rivne(row.returnDet,ss.returnDet)==1) |
(c==3&&rivne(row.categoryDet,ss.categoryDet)==1) | (c==4&&rivne(row.company,ss.company)==1)|
(c==5&&row.lifetimeDet==ss.lifetimeDet) | (c==6&&row.salesDet==ss.salesDet) |
(c==7&&row.priceDet==ss.priceDet) | (c==8&&row.nameDet==ss.nameDet) |
(c==9&&row.securityDet==ss.securityDet) | (c==10&&row.Number==ss.Number)
)
print_row(row);
}
row.id=0;
}
fseek(db,0,0);
getch();
}
int createDB(void){
FILE *tmp;
char db_name[255];
printf("DataBase name= "); scanf("%s",&db_name);
tmp=fopen(db_name,"w+");
fclose(tmp);
printf("Database has been create! choose as default? Y/N:");
if(quest()){
strcpy(file_name,db_name);
db=fopen(file_name,"r");
return 1;
}
return 0;
}
int menu_pd(void){
char c;
system("pause");
printf("DATABASE, Guz Volodya, KN-25, Laboratorna2\n\n");
printf("********[Database: %10s]********\n",&file_name);
printf("* 1- insert row *\n");
printf("* 2- show all rows *\n");
printf("* 3- search by key *\n");
printf("* 4- update by key *\n");
printf("* 5- delete by key *\n");
printf("* *\n");
printf("* 0- exit *\n");
printf("**************************************\n");
c=getchar();
switch (c) {
case '1':{InsertRow();break;}
case '2':{showAll();break;}
case '3':{Search();break;}
case '4':{Update();break;}
case '5':{Delete();break;}
case '0':{return 0;}
}
return 1;
}
int menu_db(void){
int c=0;
system("pause");
printf("DATABASE, Guz Volodya, KN-25, LABORATORNA2\n\n");
printf(" 1 - Select DataBase\n");
printf(" 2 - Create DataBase\n");
printf("\tYour choose:");
while(c!=1&&c!=2){
fflush(stdin);
scanf("%i",&c);
}
if(c==1&&db_conect()){
return 1;
}else if(c==2&&createDB()){
return 1;
}else return 0;
}
int main(){
system ("mode con cols=110");
if(menu_db()==0)return 0;
//db_conect();
while(menu_pd()==1){}
return 0;
return 0;
}
//---------------------------------------------------------------------------
Основне меню:
Створення файлу бази даних:
Вставлення нового запису в базу даних:
/
Друк бази даних на екран:
Пошук за ключем в базі даних:
Видалення запису за ключем в базі даних:
Модифікація запису за ключем в базі даних:
/
Висновок
При виконанні даної лабораторнії роботі я розглянув органiзацiю i ведення файлiв прямого доступу; набути практичнi навички у програмуваннi алгоритмiв доступу хешуванням.