Advertisement
Guest User

4B

a guest
Apr 27th, 2015
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.77 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4. #include <math.h>
  5. #define scanf_s scanf
  6. #define SIZE 113
  7. typedef struct Item{ // тип – элемент таблицы; определяется в соответствии с заданием
  8.     int busy; // признак занятости эл-та
  9.     int key;
  10.     int release; //версия
  11.     char *info;
  12. } Item;
  13. typedef struct Table{
  14.     Item *item;
  15. }Table;
  16. char *getStr();
  17. void ignore();
  18. int getInt(int *a);
  19. int dialog(char *msgs[], int N);
  20. int D_Add(Table *ptab);
  21. void D_Find(Table *tab);
  22. void D_Delete(Table *tab);
  23. void D_Show(Table *tab);
  24. void init(Table *tab);
  25. int show(Table *tab, int size, char *msg);
  26. Table *delete(Table *tab, int key);
  27. Table * find(Table *ptab, int key, int release);
  28. int tableToFile(FILE *fd, Table *tab, char *fname);
  29. // Альтернативы меню для организации диалога
  30. const char *msgs[] = { "0. Quit", "1. Add", "2. Find", "3. Delete", "4. Show" }; // список альтернатив
  31. const int NMsgs = sizeof(msgs) / sizeof(msgs[0]); // количество альтернатив
  32.  
  33. int(*fptr[])(Table *) = { NULL, D_Add, D_Find, D_Delete, D_Show };
  34. int main(){
  35.     Table table = { NULL };
  36.     char *fname = "file.bin";
  37.     FILE *fid = NULL;
  38.    
  39.     init(&table);
  40.     int rc;
  41.     while (rc = dialog(msgs, NMsgs)){
  42.         if (!fptr[rc](&table))
  43.             break;
  44.     }
  45.     tableToFile(fid,&table,fname);
  46.    
  47. }
  48. int tableToFile(FILE *fd, Table *tab, char *fname){
  49.     int size =0;
  50.     int res;
  51.     int i =0;
  52.     int len;
  53.    
  54.     if(fd = fopen(fname,"w+b"));
  55.     {
  56.         printf("не могу открыть файл '%s'",fname);
  57.         return 0;
  58.     }
  59.     //первым будет размер талицы
  60.     res = fwrite(&size,1,sizeof(int),fd);
  61.     while(i<SIZE){
  62.         if(tab->item[i].busy == 1){
  63.             len = strlen(tab->item[i].info)+1;
  64.             res+=fwrite(&(tab->item[i].key),1,sizeof(int),fd);
  65.             res+=fwrite(&(tab->item[i].release),1,sizeof(int),fd);
  66.             res+=fwrite(&len,1,sizeof(int),fd);
  67.             res+=fwrite(tab->item[i].info,len,sizeof(char),fd);
  68.         }
  69.         i++;
  70.     }
  71.     fclose (fd);
  72. }
  73. void init(Table *tab){
  74.     int i;
  75.     tab->item = calloc(SIZE, sizeof(Item));
  76.     for (i = 0; i < SIZE; i++){
  77.         tab->item[i].key = -1;
  78.     }
  79. }
  80. int Hash(int key, int i){ //двойная хэшфункция
  81.     float gold = 0.6180333;
  82.     //int f1 = SIZE*fmod(key*gold, 1);
  83.     int f1 = key%SIZE;
  84.     int f2 = key % (SIZE - 1) + 1;
  85.     int hash = (f1 + i*f2) % SIZE;
  86.     return hash;
  87. }
  88. char *getStr(){
  89.     char buf[21];
  90.     int n, len = 0, curLen;
  91.     char *ptr = (char *)malloc(1);
  92.     *ptr = '\0';
  93.     do{
  94.         n = scanf_s("%20[^\n]", buf, 21);
  95.         if (n < 0){
  96.             free(ptr);
  97.             ptr = NULL;
  98.             continue;
  99.         }
  100.         if (n > 0){
  101.             curLen = strlen(buf);
  102.             len += curLen;
  103.             ptr = (char *)realloc(ptr, len + 1);
  104.             strcat(ptr, buf);
  105.         }
  106.         else
  107.         scanf_s("%*c", 0);
  108.     } while (n > 0);
  109.    
  110.     return ptr;
  111. }
  112. int getInt(int *a){
  113.     int n;
  114.     do{
  115.         n = scanf_s("%d", a, sizeof(int));
  116.         if (n < 0)return 0;
  117.         if (n == 0){
  118.             printf("Input error!! Repeat, please\n");
  119.             scanf_s("%*c", 0);
  120.         }
  121.     } while (n == 0);
  122.    
  123.     return 1;
  124. }
  125. void ignore(){
  126.     scanf_s("%*[^\n]", 0);
  127.     scanf_s("%*c", 0);
  128. }
  129. int dialog(char *msgs[], int N){
  130.     char *errmsg = "";
  131.     int rc;
  132.     int i, n;
  133.     printf("========= MENU ========\n");
  134.     do{
  135.         puts(errmsg);
  136.         errmsg = "You are wrong. Repeat, please!";
  137.        
  138.         // вывод списка альтернатив
  139.         for (i = 0; i < N; ++i)
  140.         puts(msgs[i]);
  141.         printf("Make your choice: —> ");
  142.        
  143.         n = getInt(&rc); // ввод номера альтернативы
  144.         if (n == 0) // конец файла - конец работы
  145.         rc = 0;
  146.     } while (rc < 0 || rc >= N);
  147.    
  148.     return rc;
  149. }
  150. const char *errmsgs[] = { "Table overflow", "OK" };
  151. int D_Add(Table *ptab)
  152. {
  153.     int k, rc = 0, n;
  154.     char *info = NULL;
  155.     printf("Enter key: —> ");
  156.     n = getInt(&k);
  157.     if (n == 0)   return 0; // обнаружен конец файла
  158.     ignore(); // удаляет все оставшиеся символы из буфера ввода
  159.    
  160.     printf("Enter info: ");
  161.     info = getStr(); // вся строка вводится целиком
  162.  
  163.     if (info == NULL)
  164.     return 0; // обнаружен конец файла
  165.    
  166.     rc = insert(ptab, k, info); // вставка элемента в таблицу
  167.     free(info); // если элемент вставляется в таблицу - вставляется его копия
  168.     printf("\n======= RESULT ========\n");
  169.     printf(" %s: %d\n", errmsgs[rc], k);
  170.     printf("=======================\n");
  171.     return 1;
  172. }
  173.  
  174. void D_Find(Table *tab){
  175.     int k, rc = 0, n;
  176.     char *info = NULL;
  177.     int rel;
  178.     printf("Enter key: —> ");
  179.     n = getInt(&k);
  180.     if (n == 0)
  181.     return 0; // обнаружен конец файла
  182.    
  183.     ignore(); // удаляет все оставшиеся символы из буфера ввода
  184.    
  185.     printf("Enter release(-1 if u want all): ");
  186.     n = getInt(&rel); // вся строка вводится целиком
  187.     if (n == 0)
  188.     return 0; // обнаружен конец файла
  189.     find(tab, k, rel);
  190.     return 1;
  191. }
  192. /*
  193. void D_Delete(Table *tab){
  194.     int k, rc = 0, n;
  195.     char *info = NULL;
  196.     int rel;
  197.     printf("Enter key: —> ");
  198.     n = getInt(&k);
  199.     if (n == 0)
  200.     return 0; // обнаружен конец файла
  201.    
  202.     ignore(); // удаляет все оставшиеся символы из буфера ввода
  203.    
  204.     printf("Enter release: ");
  205.     n = getInt(&rel); // вся строка вводится целиком
  206.     if (n == 0)
  207.     return 0; // обнаружен конецфайла
  208.     delete(tab,k, rel);
  209.     return 1;
  210. }*/
  211. void D_Show(Table *tab){
  212.     show(tab, SIZE,"");
  213. }
  214. int show(Table *tab, int size, char *msg){
  215.     int Len = strlen("+---------------------------------------------------+\n");
  216.     int i = 0;
  217.     printf("+---------------------------------------------------+\n");
  218.     printf("| Busy | Key | Release |Info                        |\n");
  219.     printf("+---------------------------------------------------+\n");
  220.     if (size == 0)printf("%35s\n", msg);
  221.     for (i = 0; i < size; i++){
  222.         if (tab->item[i].busy == 1){
  223.             printf("|%9d|%5d|%9d|%25s|\n", tab->item[i].busy, tab->item[i].key, tab->item[i].release, tab->item[i].info);
  224.         }
  225.     }
  226.     printf("+---------------------------------------------------+\n");
  227. }
  228. //Функции работы с таблицей
  229. int insert(Table *ptab, int key, char *info){
  230.     int size = strlen(info)* sizeof(info);
  231.     int rel = 0;// версия эл-та
  232.     int flag = 0, i;/*пока переменная индекс равана -1 цикл выполняется*/
  233.     int hash;
  234.     for (i = 0; flag == 0 && i < SIZE; i++){
  235.         hash = Hash(key, i);
  236.         if (ptab->item[hash].busy <= 0){ // эл-т свободен (0)
  237.             ptab->item[hash].busy = 1;
  238.             ptab->item[hash].key = key;
  239.             ptab->item[hash].release = i;
  240.             ptab->item[hash].info = calloc(strlen(info), sizeof(info));
  241.             strcpy(ptab->item[hash].info, info);
  242.            
  243.             flag = 1;
  244.         }
  245.        
  246.     }
  247.     return flag;//0 - !успешно 1- успешно
  248. }
  249.  
  250. //************************************
  251. // Method: find
  252. // Returns: NULL - если не найденно
  253. // Qualifier:
  254. //************************************
  255. Table * find(Table *ptab, int key, int release){//если release -1 то вывести все
  256.     char *msg = "404 - NOT FOUND";
  257.     Table result = { NULL };
  258.     Table *res = &result;
  259.     int n = 0;
  260.     int i = 0;
  261.     int size = 1;
  262.     int j = Hash(key, i);
  263.     result.item = calloc(1, sizeof(Item));
  264.     while (ptab->item[j].busy != 0 && n < SIZE){
  265.         if (ptab->item[j].busy == 1 && ptab->item[j].key == key && release < 0){
  266.             res->item[i].busy = 1;
  267.             res->item[i].key = key;
  268.             res->item[i].release = ptab->item[j].release;
  269.             res->item[i].info = ptab->item[j].info;
  270.             size++;
  271.         }
  272.         if (ptab->item[j].busy == 1 && ptab->item[j].key == key && ptab->item[j].release == release){
  273.             res->item[0].busy = 1;
  274.             res->item[0].key = key;
  275.             res->item[0].release = ptab->item[j].release;
  276.             res->item[0].info = ptab->item[j].info;
  277.             show(res, 1, msg);
  278.             return res;
  279.         }
  280.         n++;
  281.         i++;
  282.         j = Hash(key, i);
  283.         result.item = realloc(result.item, (size + 1)* sizeof(Item));
  284.     }
  285.     result.item = realloc(result.item, size* sizeof(Item));
  286.     show(res, i, msg);
  287.     return res;
  288. }
  289. Table *delete(Table *tab, int key){
  290.     const char *error[] = { "RElEASE NOT EXIST", "KEY NOT EXIST" };
  291.     int n = 0, i = 0;
  292.     int j = Hash(key, i);
  293.     while (tab->item[j].busy > 0 && n < SIZE){
  294.         if (tab->item[j].busy == 1 && tab->item[j].key == key){
  295.             tab->item[j].busy = -1;
  296.         }
  297.         i++;
  298.         n++;
  299.         j = Hash(key, i);
  300.     }
  301.     return 0;
  302. }
  303.  
  304. void D_Delete(Table *tab){
  305.     int k, rc = 0, n;
  306.     char *info = NULL;
  307.     int rel;
  308.     printf("Enter key: —> ");
  309.     n = getInt(&k);
  310.     if (n == 0)
  311.     return 0; // обнаружен конец файла
  312.    
  313.     ignore(); // удаляет все оставшиеся символы из буфера ввода
  314.     if (n == 0)
  315.     return 0; // обнаружен
  316.     delete(tab, k);
  317.     return 1;
  318. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement