МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра САПР
Звіт
до лабораторної роботи №2
на тему:
«ПРЯМИЙ МЕТОД ДОСТУПУ ДО ФАЙЛІВ НА ЗОВНІШНІХ ЗАПАМ’ЯТОВУЮЧИХ ПРИСТРОЯХ»
Тема:
Прямий метод доступу до файлів на зовнішніх запам’ятовуючих пристроях.
Мета:
Розглянути органiзацiю i ведення файлiв прямого доступу; набути практичнi навички у програмуваннi алгоритмiв доступу хешуванням.
Завдання:
Реалізувати програму прямого доступу до файлів на зовнішньому запам’ятовуючому пристрої на тему «Комп’ютерні ігри». Забезпечити можливість:
Створення БД.
Вставка елементу в БД.
Видалення запису з БД.
Модифікація запису.
Пошук.
Перегляд.
Теоретичні відомості:
МЕТОД ПРЯМОГО ДОСТУПУ
Головною особливiстю прямого методу доступу є взаємна однозначна вiдповiднiсть мiж ключем запису i його фiзичною адресою. Фiзичне розмiщення запису визначається безпосередньо iз значення ключа.
Створивши файл прямого доступу i видiливши для нього необхiдну дiлянку пам’ятi, можна вставляти записи у будь-якi мiсця файла. Перевага такого пiдходу над послiдовною органiзацiєю файла полягає у тому, що вдається отримати запис за заданим значенням ключа без попереднього перегляду всiх попереднiх записiв файла.
ЕФЕКТИВНІСТЬ ЗБЕРІГАННЯ залежить вiд густини ключiв. Якщо густина низька, пам’ять використовується неефективно, оскiльки резервуються адреси, що вiдповiдають вiдсутнiм ключам. У цьому випадку доцiльно використовувати для органiзацiї файла метод хешування. Пряму адресацiю можна важати частковим випадком методу хешування.
МЕТОДИ ХЕШУВАННЯ.
На практицi кiлькiсть можливих значень ключiв набагато перевищує кiлькiсть реально присутнiх у будь-який момент значень цього ключа. У цьому випадку пряма адресацiя є невигiдною, оскiльки надто багато пам’ятi резервується для записiв, яких немає i нiколи не буде у файлi. Метод хешування дає змогу уникнути цього i водночас зберегти ефективнiсть, властиву прямiй адресацiї.
На основi iнформацiї про множину фактичних значень ключiв створюється файл прямого доступу з такою кiлькiстю записiв, яка дещо перевищує фактичне значення ключiв. Вибирається функцiя хешування, яка перетворює значення ключа кожного запису в адресу блока у файлi. Зрозумiло, що хеш-функцiя h - це функцiя, яка вiдображає принцип "багато в один".
ПОШУК
Для того щоб за даним значенням ключа k знайти вiдповiдний запис, необхiдно визначити h(k) i потiм органiзувати лiнiйний пошук у блоцi, номер якого дорiвнює h(k). Цей пошук буде продовжуватися доти, поки не буде знайдений запис, значення первинного ключа якого збiгається iз заданим.
ВСТАВЛЯННЯ
Щоб вставити у файл новий запис, потрiбно за допомогою методу лiнiйного пошуку у блоцi, номер якого визначається значенням h(k), знайти вiльне мiсце. Пiсля цього на мiсце знайденого вiльного запису необхiдно розмiстити новий. Якщо при спробi помiстити новий запис у файл виявляється, що у знайденому блоцi немає вiльного мiсця, вважають, що блок переповнений.
ВИДАЛЕННЯ
Для видалення запису iз файла потрiбно, використовуючи метод лiнiйного пошуку, знайти запис у блоцi, номер якого дорiвнює h(k). Якщо запис буде знайдено то вiн видаляється, якщо нi, то очевидно, що блок був переповнений i необхiдно продовжити пошук.
МОДИФІКАЦІЯ
Якщо необхiдно модифiкувати запис, то потрiбно знайти цей запис i замiнити старi поля на новi. Нiяких iнших змiн не потрiбно.
ПЕРЕПОВНЕННЯ
Для боротьби з переповненням можуть бути використанi три методи: зв’язаних блокiв, зв’язаних записiв та прогресуючого переповнення.
Метод блокiв, зв’язаних у ланцюг, полягає у такому. Коли блок переповнюється, у ньому розмiщується вказiвник на новостворений блок, призначений тiльки для записiв, що не помiстилися до першого блока. Якщо ж новостворений блок, своєю чергою, переповнений, у нього розмiщується вказiвник, що посилається на ще один знову створений блок i т.д. У результатi буде створений зв’язаний список блокiв, для всiх записiв якого значення функцiї хешування однакове.
Головний недолiк методу зв’заних блокiв полягає у тому, що блоки переповнення часто виявляються заповненими лише кiлькома записами, а решта пам’тi витрачається даремно.
Якщо необхiдно вставити новий запис, а у блоцi, призначеному для цього, немає мiсця, цей запис розмiщується у перший блок переповнення, в якому є вiльне мiсце. Пiсля цього необхiдно вставити цей запис у зв’язаний список записiв iз тим самим значенням функцiї хешування.
Хоча у цьому методi часто використовується менше блокiв переповнення, нiж у попередньому, пошук запису, що потрапив у дiлянку переповнення, може потребувати бiльше часу.
При органiзацiї першого методу необхiдно органiзувати доступ до двох блокiв: до головного блока, номер якого визначається функцiєю хешування i до блока переповнення, що мiстить даний запис. Якщо ж використовувати другий метод, то необхiдно спочатку органiзувати доступ до головного блока, а потiм переглянути зв’язаний список записiв, що потрапили у дiлянку переповнення, тодi необхiдно, йдучи по зв’язаному списку, органiзувати доступ до блокiв доти, поки не буде знайдений блок, який мiстить шуканий запис.
Метод прогресуючого переповнення багато у чому схожий на другий метод. Вiдмiннiсть полягає у тому, що записи у блоках переповнення не об’єднуються у зв’язанi списки. У тому випадку, якщо у блоцi, номер якого визначається значенням функцiї хешування, бiльше немає мiсця, запис розмiщується у перший вiльний простiр блока переповнення. У цей блок розмiщуються записи iз рiзним значенням функцiї хешування. Для пошуку запису потрiбно спочатку органiзувати доступ до головного блока. Якщо шуканого запису немає, необхiдно, використовуючи метод лiнiйного пошуку, переглядати блоки переповнення доти, поки запис не буде знайдений. У цьому випадку будуть переглядатися навiть тi записи, що мають iншi значення функцiї хешування. Зауважимо, що другий метод має бiльшу швидкодiю, нiж третiй, оскiльки обмежує пошук лише тими записами, якi мають те саме значення функцiї хешування, що i шукана. Але третiй метод вимагає менше пам’ятi, нiж другий, оскiльки немає необхiдностi зберiгати вказiвники. Крiм того, третiй метод простiший у реалiзацiї.
ФУНКЦІЇ ХЕШУВАННЯ
Використовуючи хешування обчислюють номер блока для заданого значення первинного ключа. Вимоги до хеш-функцiї:
Забезпечення рiвномiрного розкиду значень ключiв по адресах блокiв.
Повинна якнайменше призводити до ситуацiї переповнення.
Повинна бути простою, тобто мiстити невелику кiлькiсть основних арифметичних операцiй.
Функцiю хешування вибирають у дечому довiльно. Щоб вибрати функцiю хешування, необхiдно знати, по-перше, приблизну кiлькiсть записiв у файлi i, по-друге, скiльки записiв можна помiщати у блок. Ця iнформацiя буде використовуватися для пiдрахунку кiлькостi блокiв у файлi, на основi якого можна визначити дiапазон змiни значень функцiї хешування.
Текст програми:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#define MAXNAME 40
#define MAXPLATFORM 20
#define MAXDEVELOPER 30
#define MAXPUBLISHER 30
#define MAXRELEASEDATE 10
#define MAXGENRE 20
#define MAXHOMEPAGE 20
#define MAXTRANSMITTER 3
#define MAXGRAPHICS 10
int cash,whatEdit; //cash-кеш.
long adressOfNewBlockPerepForNewAdressesRecords;
char nameOfDatabase[20];
char nameOfFile[20]; //Змінна для збереження назви нової бази даних.
FILE *fileDatabase; //Мітка для файлу ств. бази даних.
struct game {
int ID;
char name[MAXNAME];
char developer[MAXDEVELOPER];
char publisher[MAXPUBLISHER];
char platform[MAXPLATFORM];
char genre[MAXGENRE];
char homepage[MAXHOMEPAGE];
char releaseDate[MAXRELEASEDATE];
int age;
char transmitter[MAXTRANSMITTER];
int gameRate;
char graphics[MAXGRAPHICS];
long adress;
};
void updatePointing(int);
void updateCash(int);
void addRecord(struct game add);
void addSpacec(int);
void addBlockPerepov(int,long,int,int);
void ubgradeAdressesOfRecordsWithSameCash(int,long,int,int,int);
void editRecord(struct game add);
void reviewBlock(long,int,int);
void searchRecord();
int main(void) {
int menuItem,menuExit=7,menuItemP; // menuItem - змінна для зберігання вибору пункту головного меню
int yes_no; //Змінна для перевірки вибору меню кожного підменю.
int back,backGo; //Змінна для перевірки нажато "0" для виходу в гол. меню.
int bl=832,blH=24,blP=23,recSize=202,recSizeP=217,allBlockP=891; //bl-розмір блок.
long blPerepov;
struct game addGame;
system("cls");
do {
system("cls");
printf(" Menu:\n1. Creation a database.\n2. Insert the element in a database (ID).\n3. Delete an element. \n4. Edit after the key field. \n5. Review a database. \n6. Search in the database. \n7. Close a programm.\n");
printf("Choose and enter one of menu items: ");
scanf("%d",&menuItem);
if (menuItem==1) {
menuItemP=0;
printf(" -=CREATION A DATABASE=-");
printf("\n Do you want to create a new database? The old database will be deleted.\n");
printf("1. Yes\n2. No\n");
printf("Choose and enter one of menu items: ");
scanf("%d",&menuItemP);
//**Перевірка вибраний пункт підменю головного меню чи ні.
if (menuItemP==1 || menuItemP==2) {
yes_no=1;
}
else {
yes_no=0;
}
//*Перевірка чи потрібно виконувати цикл, якщо не вибраний пункт підменю.
while (yes_no!=1) {
printf("You have not chosen any menu item. Please enter once again: ");
scanf("%d",&menuItemP);
if (menuItemP==1 || menuItemP==2) {
yes_no=1;
}
}
//*Кінець - Перевірка чи потрібно виконувати цикл, якщо не вибраний пункт підменю.
//**Кінець - Перевірка вибраний пункт підменю головного меню чи ні.
if (menuItemP==1) { //Потрібно створювати базу даних???
printf("\nEnter name of the file (MAX-20): ");
scanf("%s",&nameOfFile); //Введення назви файлу бази даних.
strcat(nameOfFile,".txt"); //Додавання розширення .txt до імені.
//**Перевірка чи створений файл бази даних чи ні та виведення результату.
if ((fileDatabase=fopen(nameOfFile,"w")) == NULL) {
printf("\nAn error is at creation of file. %s.",nameOfFile);
}
else {
for (int i=0; i<11; i++) {
if (i != 10) {
long blk=ftell(fileDatabase);
printf("blk=%ld\n",blk);
fprintf(fileDatabase,"@ %d 0 0 0 0 \n",i);
}
else {
blPerepov=ftell(fileDatabase);
printf("%ld",blPerepov);
fprintf(fileDatabase,"P 0 0 0 0 0 ! ! ! ! 1\n");
}
for (int s=0; s<4; s++) {
for (int j=0; j<12; j++) {
if (j==0) {
for (int k=0; k<4; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==1) {
for (int k=0; k<21; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==2) {
for (int k=0; k<41; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==3) {
for (int k=0; k<31; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==4) {
for (int k=0; k<31; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==5) {
for (int k=0; k<11; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==6) {
for (int k=0; k<21; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==7) {
for (int k=0; k<21; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==8) {
for (int k=0; k<4; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==9) {
for (int k=0; k<11; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==10) {
for (int k=0; k<3; k++) {
fprintf(fileDatabase," ");
}
}
else if (j==11) {
fprintf(fileDatabase," ");
if (i==10) {
fprintf(fileDatabase," ");
}
}
}
if (i == 10 && s==3) {
}
else {
fprintf(fileDatabase,"\n");
}
}
}
updatePointing(blPerepov);
blPerepov=0;
printf("\nA file is successfully created. Name of file %s.",nameOfFile);
}
//**Кінець - Перевірка чи створений файл бази даних чи ні та виведення результату.
//*Перевірка чи закритий файл бази даних чи ні та виведення результату.
if (fclose(fileDatabase) != 0) {
printf("\nAn error is at closing of file %s.",nameOfFile);
}
}
//**Повернення в головне меню.
printf("\nEnter '0' for returning in a main menu: ");
scanf("%d",&backGo);
while (backGo!=0) {
printf("You have not enter '0'. Please enter once again: ");
scanf("%d",&backGo);
}
//**Кінець - Повернення в головне меню.
back=1; //Вивід головного меню дозволений.
}
else if (menuItem==2) {
printf(" -=ADD A RECORD IN THE DATABASE=-");
printf("\nEnter name of the file (MAX-20): ");
scanf("%s",&nameOfFile); //Введення назви файлу бази даних.
strcat(nameOfFile,".txt"); //Додавання розширення .txt до імені.
//**Перевірка чи створений файл бази даних чи ні та виведення результату.
if ((fileDatabase=fopen(nameOfFile,"r+")) == NULL) {
printf("\nAn error is at opening a file. %s.",nameOfFile);
}
//***Введення даних.
int yes_noGameRate=0;
printf("\nEnter next information for a record in a database.");
printf("\n1. Enter ID of the game: ");
scanf("%d",&addGame.ID);
updateCash(addGame.ID);
printf("2. Enter platform (MAX-10): ");
scanf("%s",&addGame.platform);
printf("3. Enter name of the game (MAX-40): ");
scanf("%s",&addGame.name);
printf("4. Enter developer (MAX-30): ");
scanf("%s",&addGame.developer);
printf("5. Enter publisher (MAX-30): ");
scanf("%s",&addGame.publisher);
printf("6. Enter release date (MAX-10): ");
scanf("%s",&addGame.releaseDate);
printf("7. Enter genre (MAX-20): ");
scanf("%s",&addGame.genre);
printf("8. Enter homepage (MAX-20): ");
scanf("%s",&addGame.homepage);
printf("9. Enter transmitter (MAX-10): ");
scanf("%s",&addGame.transmitter);
printf("10. Enter graphics (MAX-10): ");
scanf("%s",&addGame.graphics);
printf("11. Enter age (MAX-3): ");
scanf("%d",&addGame.age);
printf("12. Enter game rate (1,2,3,4 or 5): ");
scanf("%d",&addGame.gameRate);
if (addGame.gameRate==1 || addGame.gameRate==2 || addGame.gameRate==3 || addGame.gameRate==4 || addGame.gameRate== 5) {
yes_noGameRate=1;
}
while (yes_noGameRate!=1) {
printf("You have not enter 1, 2, 3, 4 or 5. Please enter once again: ");
scanf("%d",&addGame.gameRate);
if (addGame.gameRate==1 || addGame.gameRate==2 || addGame.gameRate==3 || addGame.gameRate==4 || addGame.gameRate== 5) {
yes_noGameRate=1;
}
}
//***Кінець - Введення даних.
//**Вивід даних.
printf("\n----------------------------------");
printf("\nYour dates:\n");
printf("\nID: %d\nPlatform: %s\nName: %s\nDeveloper: %s\nPublisher: %s\nRelease date: %s\nGenre: %s\nHomepage: %s\nTransmitter: %s\nGraphics: %s\nAge: %d\nGame rate: %d\nCash: %d\n",addGame.ID,addGame.platform,addGame.name,addGame.developer,addGame.publisher,addGame.releaseDate,addGame.genre,addGame.homepage,addGame.transmitter,addGame.graphics,addGame.age,addGame.gameRate,cash);
printf("\n----------------------------------\n");
//**Кінець - Вивід даних.
long point; //Змінна для збереження адреси зміщення блоку.
int addRecordYes_No=0; //Запис додано в блок чи ні.
int availableSpace=0,block,freeAbstand;
switch (cash) {
case 0:
point=0; break;
case 1:
point=bl; break;
case 2:
point=bl*2; break;
case 3:
point=bl*3; break;
case 4:
point=bl*4; break;
case 5:
point=bl*5; break;
case 6:
point=bl*6; break;
case 7:
point=bl*7; break;
case 8:
point=bl*8; break;
case 9:
point=bl*9; break;
}
//Додвання запису в простий блок в залежності від кешу.
fseek(fileDatabase,point,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("Block=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==0) {
printf("\nFree place. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"1");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+blH+recSize*i,SEEK_SET);
addRecord(addGame);
addRecordYes_No=1;
break;
}
else {
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
//Якщо нема місця, то перевірка блоку переповнення на вільне місце.
if (addRecordYes_No==0) {
int whereAdded;
int blocks_n;
long adressOfFirstBlockPer;
long newAdressBlockPer;
printf("\nA record is added to the block of overloaded.");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+12,SEEK_SET);
fscanf(fileDatabase,"%ld",&blPerepov);
fseek(fileDatabase,blPerepov+20,SEEK_SET);
fscanf(fileDatabase,"%d",&blocks_n);
printf("\nblocks_n=%d",blocks_n);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("\nBlock Perepov=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==0) {
printf("\nFree place. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"1");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+freeAbstand+8,SEEK_SET);
fprintf(fileDatabase,"%d",cash);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+blP+recSizeP*i,SEEK_SET);
addRecord(addGame);
fprintf(fileDatabase," %d",block);
fprintf(fileDatabase," %d",i);
fprintf(fileDatabase," 0");
addRecordYes_No=1;
ubgradeAdressesOfRecordsWithSameCash(cash,blPerepov,block,blocks_n,allBlockP);
whereAdded=i;
break;
}
else if (availableSpace==1){
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
//Якщо нема місця в блоці переповнення, то перевірка кількості блоків і пошук вільного місця.
if (addRecordYes_No==0) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+20,SEEK_SET);
fscanf(fileDatabase,"%d",&blocks_n);
printf("\nblocks_n=%d",blocks_n);
if (blocks_n > 1) {
adressOfFirstBlockPer=blPerepov;
printf("\nZnaxodgennja vil'noho miszja:");
printf("\nblPerepov=%ld",blPerepov);
for (int k=0; k<block; k++) {
adressOfFirstBlockPer=adressOfFirstBlockPer-allBlockP;
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
}
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
for (int g=0; g<blocks_n; g++) {
fseek(fileDatabase,0L,SEEK_SET);
printf("\ng=%d",g);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*g,SEEK_SET);
newAdressBlockPer=ftell(fileDatabase);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("\nBlock Perepov=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==0) {
printf("\nFree place. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,newAdressBlockPer+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"1");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,newAdressBlockPer+freeAbstand+8,SEEK_SET);
fprintf(fileDatabase,"%d",cash);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,newAdressBlockPer+blP+recSizeP*i,SEEK_SET);
addRecord(addGame);
fprintf(fileDatabase," %d",block);
fprintf(fileDatabase," %d",i);
fprintf(fileDatabase," 0");
addRecordYes_No=1;
updatePointing(newAdressBlockPer);
ubgradeAdressesOfRecordsWithSameCash(cash,newAdressBlockPer,block,blocks_n,allBlockP);
whereAdded=i;
break;
}
else if (availableSpace==1){
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
if (addRecordYes_No==1) {
break;
}
}
}
//Якщо всі блоки переповнення зайняті, то створення нового блоку переповнення
if (addRecordYes_No==0) {
printf("\nA vil'noho miszja nema:");
fseek(fileDatabase,0L,SEEK_SET);
addBlockPerepov(blocks_n,blPerepov,allBlockP,block);
blPerepov=ftell(fileDatabase);
printf("\nA record is added to the block of overloaded.");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+12,SEEK_SET);
fscanf(fileDatabase,"%ld",&blPerepov);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("\nBlock Perepov=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==0) {
printf("\nFree place. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"1");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+freeAbstand+8,SEEK_SET);
fprintf(fileDatabase,"%d",cash);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+blP+recSizeP*i,SEEK_SET);
addRecord(addGame);
fprintf(fileDatabase," %d",block);
fprintf(fileDatabase," %d",i);
fprintf(fileDatabase," 0");
addRecordYes_No=1; ubgradeAdressesOfRecordsWithSameCash(cash,adressOfNewBlockPerepForNewAdressesRecords,block,blocks_n+1,allBlockP);
whereAdded=i;
break;
}
else if (availableSpace==1){
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
}
}
}
if (fclose(fileDatabase) != 0) {
printf("\nAn error is at closing of file %s.",nameOfFile);
}
//**Повернення в головне меню.
printf("\nEnter '0' for returning in a main menu: ");
scanf("%d",&backGo);
while (backGo!=0) {
printf("You have not enter '0'. Please enter once again: ");
scanf("%d",&backGo);
}
//**Кінець - Повернення в головне меню.
back=1; //Вивід головного меню дозволений.
}
else if (menuItem==3) {
printf(" -=DELETE A RECORD IN THE DATABASE=-");
printf("\nEnter name of the file (MAX-20): ");
scanf("%s",&nameOfFile); //Введення назви файлу бази даних.
strcat(nameOfFile,".txt"); //Додавання розширення .txt до імені.
//**Перевірка чи створений файл бази даних чи ні та виведення результату.
if ((fileDatabase=fopen(nameOfFile,"r+")) == NULL) {
printf("\nAn error is at opening a file. %s.",nameOfFile);
}
printf("\n1. Enter ID of the record what you want to delete: ");
scanf("%d",&addGame.ID);
updateCash(addGame.ID);
long point; //Змінна для збереження адреси зміщення блоку.
int deleteRecordYes_No=0; //Запис додано в блок чи ні.
int availableSpace=1,block,freeAbstand,idBl;
switch (cash) {
case 0:
point=0; break;
case 1:
point=bl; break;
case 2:
point=bl*2; break;
case 3:
point=bl*3; break;
case 4:
point=bl*4; break;
case 5:
point=bl*5; break;
case 6:
point=bl*6; break;
case 7:
point=bl*7; break;
case 8:
point=bl*8; break;
case 9:
point=bl*9; break;
}
//Видалення з простого блоку в залежності від кешу.
fseek(fileDatabase,point,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("Block=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==1) {
printf("\nTaked space. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+blH+recSize*i,SEEK_SET);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+blH+recSize*i,SEEK_SET);
for (int i=0; i<200; i++) {
fprintf(fileDatabase," ");
}
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"0");
printf("\nRecord was deleted.");
deleteRecordYes_No=1;
break;
}
freeAbstand=freeAbstand+2;
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+freeAbstand,SEEK_SET);
}
else {
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
//Пошук першого запису з однаковим кешом
if (deleteRecordYes_No==0) {
int blocks_n,cashBl;
long adressOfFirstBlockPer;
fseek(fileDatabase,point+12,SEEK_SET);
fscanf(fileDatabase,"%ld",&blPerepov);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+20,SEEK_SET);
fscanf(fileDatabase,"%d",&blocks_n);
printf("\nblocks_n=%d",blocks_n);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
adressOfFirstBlockPer=blPerepov;
printf("\nSearch ID:");
printf("\nblPerepov=%ld",blPerepov);
for (int k=0; k<block; k++) {
adressOfFirstBlockPer=adressOfFirstBlockPer-allBlockP;
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
}
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
long deleteOrNot;
int firstRecordCash,zuklDelete=0;
for (int s=0; s<blocks_n; s++) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("\nBlock=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==1) {
printf("\nTaked space. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+freeAbstand+8,SEEK_SET);
fscanf(fileDatabase,"%d",&cashBl);
fseek(fileDatabase,0L,SEEK_SET);
if (cashBl==cash) {
printf("\nFirst record with identical cash searched.");
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+23+recSizeP*i,SEEK_SET);
deleteOrNot=ftell(fileDatabase);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot,SEEK_SET);
for (int i=0; i<215; i++) {
fprintf(fileDatabase," ");
}
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+freeAbstand,SEEK_SET);
fprintf(fileDatabase,"0");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+freeAbstand+8,SEEK_SET);
fprintf(fileDatabase,"!");
updatePointing(adressOfFirstBlockPer+allBlockP*s);
ubgradeAdressesOfRecordsWithSameCash(cash, adressOfFirstBlockPer+allBlockP*s, block, blocks_n, allBlockP);
printf("\nRecord was deleted.");
deleteRecordYes_No=1;
}
else {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot+205,SEEK_SET);
fscanf(fileDatabase,"%ld",&deleteOrNot);
}
firstRecordCash=1;
break;
}
freeAbstand=freeAbstand+2;
}
else {
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
if (firstRecordCash==1) {
break;
}
}
//Запис знайдений, тепер пошук по адресах.
if (deleteRecordYes_No==0) {
int whatBlockP,whatPlace,pr=1;
printf("\n=======================Vxid v powyk po adresax=============================");
while (zuklDelete==deleteRecordYes_No) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot,SEEK_SET);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot+201,SEEK_SET);
fscanf(fileDatabase,"%d",&whatBlockP);
printf("\nwhatBlockP===%d",whatBlockP);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot+203,SEEK_SET);
fscanf(fileDatabase,"%d",&whatPlace);
printf("\nwhatPlace===%d",whatPlace);
fseek(fileDatabase,0L,SEEK_SET);
if (whatPlace==0) {
pr=0;
}
else if (whatPlace==1) {
pr=2;
}
else if (whatPlace==2) {
pr=4;
}
else if (whatPlace==3) {
pr=6;
}
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*whatBlockP+4+pr,SEEK_SET);
fprintf(fileDatabase,"0");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*whatBlockP+4+pr+8,SEEK_SET);
fprintf(fileDatabase,"!");
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot,SEEK_SET);
for (int i=0; i<215; i++) {
fprintf(fileDatabase," ");
}
updatePointing(adressOfFirstBlockPer+allBlockP*whatBlockP);
ubgradeAdressesOfRecordsWithSameCash(cash, adressOfFirstBlockPer+allBlockP*whatBlockP, whatBlockP, blocks_n, allBlockP);
printf("\nRecord was deleted.");
deleteRecordYes_No=1;
}
else {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,deleteOrNot+205,SEEK_SET);
fscanf(fileDatabase,"%ld",&deleteOrNot);
}
}
}
}
if (fclose(fileDatabase) != 0) {
printf("\nAn error is at closing of file %s.",nameOfFile);
}
//**Повернення в головне меню.
printf("\nEnter '0' for returning in a main menu: ");
scanf("%d",&backGo);
while (backGo!=0) {
printf("You have not enter '0'. Please enter once again: ");
scanf("%d",&backGo);
}
//**Кінець - Повернення в головне меню.
back=1; //Вивід головного меню дозволений.
}
else if (menuItem==4) {
printf(" -=EDIT A RECORD IN THE DATABASE=-");
printf("\nEnter name of the file (MAX-20): ");
scanf("%s",&nameOfFile); //Введення назви файлу бази даних.
strcat(nameOfFile,".txt"); //Додавання розширення .txt до імені.
//**Перевірка чи створений файл бази даних чи ні та виведення результату.
if ((fileDatabase=fopen(nameOfFile,"r+")) == NULL) {
printf("\nAn error is at opening a file. %s.",nameOfFile);
}
printf("\n1. Enter ID of the record what you want to edit: ");
scanf("%d",&addGame.ID);
updateCash(addGame.ID);
int yes_noP=0,menuItemEdit;
while (yes_noP!=1) {
system("cls");
printf("\nWhat you want to edit: ");
printf("\n1. Platform\n2. Name\n3. Developer\n4. Publisher\n5. Release date\n6. Genre\n7. Homepage\n8. Transmitter\n9. Graphics\n10. Age\n11. Game rate\n");
printf("Choose and enter one of menu items: ");
scanf("%d",&menuItemEdit);
if (menuItemEdit==1) {
printf("Enter platform (MAX-10): ");
scanf("%s",&addGame.platform);
whatEdit=1;
yes_noP=1;
}
else if (menuItemEdit==2) {
printf("Enter name (MAX-40): ");
scanf("%s",&addGame.name);
whatEdit=2;
yes_noP=1;
}
else if (menuItemEdit==3) {
printf("Enter Developer (MAX-30): ");
scanf("%s",&addGame.developer);
whatEdit=3;
yes_noP=1;
}
else if (menuItemEdit==4) {
printf("Enter Publisher (MAX-30): ");
scanf("%s",&addGame.publisher);
whatEdit=4;
yes_noP=1;
}
else if (menuItemEdit==5) {
printf("Enter Release date (MAX-10): ");
scanf("%s",&addGame.releaseDate);
whatEdit=5;
yes_noP=1;
}
else if (menuItemEdit==6) {
printf("Enter Genre (MAX-20): ");
scanf("%s",&addGame.genre);
whatEdit=6;
yes_noP=1;
}
else if (menuItemEdit==7) {
printf("Enter Homepage (MAX-20): ");
scanf("%s",&addGame.homepage);
whatEdit=7;
yes_noP=1;
}
else if (menuItemEdit==8) {
printf("Enter Transmitter (MAX-10): ");
scanf("%s",&addGame.transmitter);
whatEdit=8;
yes_noP=1;
}
else if (menuItemEdit==9) {
printf("Enter Graphics (MAX-10): ");
scanf("%s",&addGame.graphics);
whatEdit=9;
yes_noP=1;
}
else if (menuItemEdit==10) {
printf("Enter Age: ");
scanf("%d",&addGame.age);
whatEdit=10;
yes_noP=1;
}
else if (menuItemEdit==11) {
printf("Enter Game Rate: ");
scanf("%d",&addGame.gameRate);
whatEdit=11;
yes_noP=1;
}
}
long point; //Змінна для збереження адреси зміщення блоку.
int editRecordYes_No=0; //Запис додано в блок чи ні.
int availableSpace=1,block,freeAbstand,idBl;
switch (cash) {
case 0:
point=0; break;
case 1:
point=bl; break;
case 2:
point=bl*2; break;
case 3:
point=bl*3; break;
case 4:
point=bl*4; break;
case 5:
point=bl*5; break;
case 6:
point=bl*6; break;
case 7:
point=bl*7; break;
case 8:
point=bl*8; break;
case 9:
point=bl*9; break;
}
//Видалення з простого блоку в залежності від кешу.
fseek(fileDatabase,point,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("Block=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==1) {
printf("\nTaked space. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+blH+recSize*i,SEEK_SET);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
if (whatEdit==1) {
fseek(fileDatabase,point+blH+recSize*i+4,SEEK_SET);
}
if (whatEdit==2) {
fseek(fileDatabase,point+blH+recSize*i+25,SEEK_SET);
}
if (whatEdit==3) {
fseek(fileDatabase,point+blH+recSize*i+66,SEEK_SET);
}
if (whatEdit==4) {
fseek(fileDatabase,point+blH+recSize*i+97,SEEK_SET);
}
if (whatEdit==5) {
fseek(fileDatabase,point+blH+recSize*i+128,SEEK_SET);
}
if (whatEdit==6) {
fseek(fileDatabase,point+blH+recSize*i+139,SEEK_SET);
}
if (whatEdit==7) {
fseek(fileDatabase,point+blH+recSize*i+160,SEEK_SET);
}
if (whatEdit==8) {
fseek(fileDatabase,point+blH+recSize*i+181,SEEK_SET);
}
if (whatEdit==9) {
fseek(fileDatabase,point+blH+recSize*i+185,SEEK_SET);
}
if (whatEdit==10) {
fseek(fileDatabase,point+blH+recSize*i+196,SEEK_SET);
}
if (whatEdit==11) {
fseek(fileDatabase,point+blH+recSize*i+199,SEEK_SET);
}
editRecord(addGame);
printf("\nRecord was edited.");
editRecordYes_No=1;
break;
}
freeAbstand=freeAbstand+2;
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,point+freeAbstand,SEEK_SET);
}
else {
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
//Пошук першого запису з однаковим кешом
if (editRecordYes_No==0) {
int blocks_n,cashBl;
long adressOfFirstBlockPer;
fseek(fileDatabase,point+12,SEEK_SET);
fscanf(fileDatabase,"%ld",&blPerepov);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov+20,SEEK_SET);
fscanf(fileDatabase,"%d",&blocks_n);
printf("\nblocks_n=%d",blocks_n);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,blPerepov,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
adressOfFirstBlockPer=blPerepov;
printf("\nSearch ID:");
printf("\nblPerepov=%ld",blPerepov);
for (int k=0; k<block; k++) {
adressOfFirstBlockPer=adressOfFirstBlockPer-allBlockP;
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
}
printf("\nadressOfFirstBlockPer=%ld",adressOfFirstBlockPer);
long editOrNot;
int firstRecordCash,zuklEdit=0;
for (int s=0; s<blocks_n; s++) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s,SEEK_SET);
fscanf(fileDatabase,"%c"); fscanf(fileDatabase,"%c");
fscanf(fileDatabase,"%d",&block); fscanf(fileDatabase,"%c");
freeAbstand=4;
printf("\nBlock Perepov=%d",block);
for (int i=0; i<4; i++) {
fscanf(fileDatabase,"%d",&availableSpace);
printf("\navailableSpace=%d",availableSpace);
if (availableSpace==1) {
printf("\nTaked space. i=%d",i);
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+freeAbstand+8,SEEK_SET);
fscanf(fileDatabase,"%d",&cashBl);
fseek(fileDatabase,0L,SEEK_SET);
if (cashBl==cash) {
printf("\nFirst record with identical cash searched.");
fseek(fileDatabase,adressOfFirstBlockPer+allBlockP*s+23+recSizeP*i,SEEK_SET);
editOrNot=ftell(fileDatabase);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
if (whatEdit==1) {
fseek(fileDatabase,editOrNot+4,SEEK_SET);
}
if (whatEdit==2) {
fseek(fileDatabase,editOrNot+25,SEEK_SET);
}
if (whatEdit==3) {
fseek(fileDatabase,editOrNot+66,SEEK_SET);
}
if (whatEdit==4) {
fseek(fileDatabase,editOrNot+97,SEEK_SET);
}
if (whatEdit==5) {
fseek(fileDatabase,editOrNot+128,SEEK_SET);
}
if (whatEdit==6) {
fseek(fileDatabase,editOrNot+139,SEEK_SET);
}
if (whatEdit==7) {
fseek(fileDatabase,editOrNot+160,SEEK_SET);
}
if (whatEdit==8) {
fseek(fileDatabase,editOrNot+181,SEEK_SET);
}
if (whatEdit==9) {
fseek(fileDatabase,editOrNot+185,SEEK_SET);
}
if (whatEdit==10) {
fseek(fileDatabase,editOrNot+196,SEEK_SET);
}
if (whatEdit==11) {
fseek(fileDatabase,editOrNot+199,SEEK_SET);
}
editRecord(addGame);
printf("\nRecord was edited.");
editRecordYes_No=1;
}
else {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,editOrNot+205,SEEK_SET);
fscanf(fileDatabase,"%ld",&editOrNot);
}
firstRecordCash=1;
break;
}
freeAbstand=freeAbstand+2;
}
else {
fscanf(fileDatabase,"%c");
freeAbstand=freeAbstand+2;
}
}
if (firstRecordCash==1) {
break;
}
}
//Запис знайдений, тепер пошук по адресах.
if (editRecordYes_No==0) {
printf("\n=======================Vxid v powyk po adresax=============================");
while (zuklEdit==editRecordYes_No) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,editOrNot,SEEK_SET);
fscanf(fileDatabase,"%d",&idBl);
printf("\nidBl=%d",idBl);
if (idBl==addGame.ID) {
fseek(fileDatabase,0L,SEEK_SET);
fseek(fileDatabase,editOrNot,SEEK_SET);
if (whatEdit==1) {
fseek(fileDatabase,editOrNot+4,SEEK_SET);
}
if (whatEdit==2) {
fseek(fileDatabase,editOrNot+25,SEEK_SET);
}
if (whatEdit==3) {
fseek(fileDatabase,editOrNot+66,SEEK_SET);
}
if (whatEdit==4) {
fseek(fileDatabase,editOrNot+97,SEEK_SET);
}
if (whatEdit==5) {
fseek(fileDatabase,editOrNot+128,SEEK_SET);
}
if (whatEdit==6) {
fseek(fileDatabase,editOrNot+139,SEEK_SET);
}
if (whatEdit==7) {
fseek(fileDatabase,editOrNot+160,SEEK_SET);
}
if (whatEdit==8) {
fseek(fileDatabase,editOrNot+181,SEEK_SET);
}
if (whatEdit==9) {
fseek(fileDatabase,editOrNot+185,SEEK_SET);
}
if (whatEdit==10) {
fseek(fileDatabase,editO...