Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include <math.h>
- #define scanf_s scanf
- #define SIZE 113
- typedef struct Item{ // тип – элемент таблицы; определяется в соответствии с заданием
- int busy; // признак занятости эл-та
- int key;
- int release; //версия
- char *info;
- } Item;
- typedef struct Table{
- Item *item;
- }Table;
- char *getStr();
- void ignore();
- int getInt(int *a);
- int dialog(char *msgs[], int N);
- int D_Add(Table *ptab);
- void D_Find(Table *tab);
- void D_Delete(Table *tab);
- void D_Show(Table *tab);
- void init(Table *tab);
- int show(Table *tab, int size, char *msg);
- Table *delete(Table *tab, int key);
- Table * find(Table *ptab, int key, int release);
- int tableToFile(FILE *fd, Table *tab, char *fname);
- // Альтернативы меню для организации диалога
- const char *msgs[] = { "0. Quit", "1. Add", "2. Find", "3. Delete", "4. Show" }; // список альтернатив
- const int NMsgs = sizeof(msgs) / sizeof(msgs[0]); // количество альтернатив
- int(*fptr[])(Table *) = { NULL, D_Add, D_Find, D_Delete, D_Show };
- int main(){
- Table table = { NULL };
- char *fname = "file.bin";
- FILE *fid = NULL;
- init(&table);
- int rc;
- while (rc = dialog(msgs, NMsgs)){
- if (!fptr[rc](&table))
- break;
- }
- tableToFile(fid,&table,fname);
- }
- int tableToFile(FILE *fd, Table *tab, char *fname){
- int size =0;
- int res;
- int i =0;
- int len;
- if(fd = fopen(fname,"w+b"));
- {
- printf("не могу открыть файл '%s'",fname);
- return 0;
- }
- //первым будет размер талицы
- res = fwrite(&size,1,sizeof(int),fd);
- while(i<SIZE){
- if(tab->item[i].busy == 1){
- len = strlen(tab->item[i].info)+1;
- res+=fwrite(&(tab->item[i].key),1,sizeof(int),fd);
- res+=fwrite(&(tab->item[i].release),1,sizeof(int),fd);
- res+=fwrite(&len,1,sizeof(int),fd);
- res+=fwrite(tab->item[i].info,len,sizeof(char),fd);
- }
- i++;
- }
- fclose (fd);
- }
- void init(Table *tab){
- int i;
- tab->item = calloc(SIZE, sizeof(Item));
- for (i = 0; i < SIZE; i++){
- tab->item[i].key = -1;
- }
- }
- int Hash(int key, int i){ //двойная хэшфункция
- float gold = 0.6180333;
- //int f1 = SIZE*fmod(key*gold, 1);
- int f1 = key%SIZE;
- int f2 = key % (SIZE - 1) + 1;
- int hash = (f1 + i*f2) % SIZE;
- return hash;
- }
- char *getStr(){
- char buf[21];
- int n, len = 0, curLen;
- char *ptr = (char *)malloc(1);
- *ptr = '\0';
- do{
- n = scanf_s("%20[^\n]", buf, 21);
- if (n < 0){
- free(ptr);
- ptr = NULL;
- continue;
- }
- if (n > 0){
- curLen = strlen(buf);
- len += curLen;
- ptr = (char *)realloc(ptr, len + 1);
- strcat(ptr, buf);
- }
- else
- scanf_s("%*c", 0);
- } while (n > 0);
- return ptr;
- }
- int getInt(int *a){
- int n;
- do{
- n = scanf_s("%d", a, sizeof(int));
- if (n < 0)return 0;
- if (n == 0){
- printf("Input error!! Repeat, please\n");
- scanf_s("%*c", 0);
- }
- } while (n == 0);
- return 1;
- }
- void ignore(){
- scanf_s("%*[^\n]", 0);
- scanf_s("%*c", 0);
- }
- int dialog(char *msgs[], int N){
- char *errmsg = "";
- int rc;
- int i, n;
- printf("========= MENU ========\n");
- do{
- puts(errmsg);
- errmsg = "You are wrong. Repeat, please!";
- // вывод списка альтернатив
- for (i = 0; i < N; ++i)
- puts(msgs[i]);
- printf("Make your choice: —> ");
- n = getInt(&rc); // ввод номера альтернативы
- if (n == 0) // конец файла - конец работы
- rc = 0;
- } while (rc < 0 || rc >= N);
- return rc;
- }
- const char *errmsgs[] = { "Table overflow", "OK" };
- int D_Add(Table *ptab)
- {
- int k, rc = 0, n;
- char *info = NULL;
- printf("Enter key: —> ");
- n = getInt(&k);
- if (n == 0) return 0; // обнаружен конец файла
- ignore(); // удаляет все оставшиеся символы из буфера ввода
- printf("Enter info: ");
- info = getStr(); // вся строка вводится целиком
- if (info == NULL)
- return 0; // обнаружен конец файла
- rc = insert(ptab, k, info); // вставка элемента в таблицу
- free(info); // если элемент вставляется в таблицу - вставляется его копия
- printf("\n======= RESULT ========\n");
- printf(" %s: %d\n", errmsgs[rc], k);
- printf("=======================\n");
- return 1;
- }
- void D_Find(Table *tab){
- int k, rc = 0, n;
- char *info = NULL;
- int rel;
- printf("Enter key: —> ");
- n = getInt(&k);
- if (n == 0)
- return 0; // обнаружен конец файла
- ignore(); // удаляет все оставшиеся символы из буфера ввода
- printf("Enter release(-1 if u want all): ");
- n = getInt(&rel); // вся строка вводится целиком
- if (n == 0)
- return 0; // обнаружен конец файла
- find(tab, k, rel);
- return 1;
- }
- /*
- void D_Delete(Table *tab){
- int k, rc = 0, n;
- char *info = NULL;
- int rel;
- printf("Enter key: —> ");
- n = getInt(&k);
- if (n == 0)
- return 0; // обнаружен конец файла
- ignore(); // удаляет все оставшиеся символы из буфера ввода
- printf("Enter release: ");
- n = getInt(&rel); // вся строка вводится целиком
- if (n == 0)
- return 0; // обнаружен конецфайла
- delete(tab,k, rel);
- return 1;
- }*/
- void D_Show(Table *tab){
- show(tab, SIZE,"");
- }
- int show(Table *tab, int size, char *msg){
- int Len = strlen("+---------------------------------------------------+\n");
- int i = 0;
- printf("+---------------------------------------------------+\n");
- printf("| Busy | Key | Release |Info |\n");
- printf("+---------------------------------------------------+\n");
- if (size == 0)printf("%35s\n", msg);
- for (i = 0; i < size; i++){
- if (tab->item[i].busy == 1){
- printf("|%9d|%5d|%9d|%25s|\n", tab->item[i].busy, tab->item[i].key, tab->item[i].release, tab->item[i].info);
- }
- }
- printf("+---------------------------------------------------+\n");
- }
- //Функции работы с таблицей
- int insert(Table *ptab, int key, char *info){
- int size = strlen(info)* sizeof(info);
- int rel = 0;// версия эл-та
- int flag = 0, i;/*пока переменная индекс равана -1 цикл выполняется*/
- int hash;
- for (i = 0; flag == 0 && i < SIZE; i++){
- hash = Hash(key, i);
- if (ptab->item[hash].busy <= 0){ // эл-т свободен (0)
- ptab->item[hash].busy = 1;
- ptab->item[hash].key = key;
- ptab->item[hash].release = i;
- ptab->item[hash].info = calloc(strlen(info), sizeof(info));
- strcpy(ptab->item[hash].info, info);
- flag = 1;
- }
- }
- return flag;//0 - !успешно 1- успешно
- }
- //************************************
- // Method: find
- // Returns: NULL - если не найденно
- // Qualifier:
- //************************************
- Table * find(Table *ptab, int key, int release){//если release -1 то вывести все
- char *msg = "404 - NOT FOUND";
- Table result = { NULL };
- Table *res = &result;
- int n = 0;
- int i = 0;
- int size = 1;
- int j = Hash(key, i);
- result.item = calloc(1, sizeof(Item));
- while (ptab->item[j].busy != 0 && n < SIZE){
- if (ptab->item[j].busy == 1 && ptab->item[j].key == key && release < 0){
- res->item[i].busy = 1;
- res->item[i].key = key;
- res->item[i].release = ptab->item[j].release;
- res->item[i].info = ptab->item[j].info;
- size++;
- }
- if (ptab->item[j].busy == 1 && ptab->item[j].key == key && ptab->item[j].release == release){
- res->item[0].busy = 1;
- res->item[0].key = key;
- res->item[0].release = ptab->item[j].release;
- res->item[0].info = ptab->item[j].info;
- show(res, 1, msg);
- return res;
- }
- n++;
- i++;
- j = Hash(key, i);
- result.item = realloc(result.item, (size + 1)* sizeof(Item));
- }
- result.item = realloc(result.item, size* sizeof(Item));
- show(res, i, msg);
- return res;
- }
- Table *delete(Table *tab, int key){
- const char *error[] = { "RElEASE NOT EXIST", "KEY NOT EXIST" };
- int n = 0, i = 0;
- int j = Hash(key, i);
- while (tab->item[j].busy > 0 && n < SIZE){
- if (tab->item[j].busy == 1 && tab->item[j].key == key){
- tab->item[j].busy = -1;
- }
- i++;
- n++;
- j = Hash(key, i);
- }
- return 0;
- }
- void D_Delete(Table *tab){
- int k, rc = 0, n;
- char *info = NULL;
- int rel;
- printf("Enter key: —> ");
- n = getInt(&k);
- if (n == 0)
- return 0; // обнаружен конец файла
- ignore(); // удаляет все оставшиеся символы из буфера ввода
- if (n == 0)
- return 0; // обнаружен
- delete(tab, k);
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement