SHARE
TWEET

Untitled

a guest Apr 24th, 2019 64 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "pch.h"
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #pragma warning(disable:4996)
  8.  
  9. struct elem {
  10.     int x;
  11.     int y;
  12.     char* info;
  13. };
  14.  
  15. struct itemList {
  16.     elem* data;
  17.     itemList* prev;
  18.     itemList* next;
  19. };
  20.  
  21. struct Node {
  22.     int busy;
  23.     float xmax;
  24.     float xmin;
  25.     float ymax;
  26.     float ymin;
  27.     Node* child;
  28.     itemList itemshead;
  29. };
  30.  
  31. struct QTree {
  32.     int N;
  33.     int n;
  34.     Node* root;
  35.     FILE* fd;
  36.     char* filename;
  37. };
  38.  
  39. const char *msgs[] = { "0. Quit", "1. Add new element", "2. Find an element", "3. Delete an element", "4. Show table", "5. Save table", "6. Table properties", "7. Timing"};
  40. const char *errmsgs[] = { "Ok", "Error: Duplicate key 1", "Error: Duplicate key 2", "Error: Table overflow", "Table nullpointer", "Data nullptr" };
  41. const int NMsgs = sizeof(msgs) / sizeof(msgs[0]);
  42. const char *errmsgsdel[] = { "Ok", "Error: item not found" , "Table nullpointer", "Wrong keyspace" };
  43. const char *errload[] = { "Ok", "Tree nullptr", "Filename nullptr", "N is negative" };
  44. const char *errsave[] = { "Ok", "Nullptr file descriptor" };
  45. const char *errins[] = { "Ok", "Tree nullptr", "Element nullptr", "Error: this point already exists", "Incorrect keys: the point doesn\'t fit into the tree" };
  46. const char *errdel[] = {"Ok", ""};
  47. const char *showmsgs[] = { "1. X direct order", "2. Keys range", "3. Tree view" };
  48.  
  49. int dload(QTree* t);
  50. int dsave(QTree* t);
  51. int delTree(QTree* t);
  52. int dinsert(QTree* t);
  53. int dsearch(QTree* t);
  54. int dremove(QTree* t);
  55. int dshow(QTree* t);
  56. int properties(QTree *t);
  57. int save(QTree* t);
  58. int rmv(QTree* t, int x, int y);
  59. int insert(QTree* t, elem* e);
  60. int getInt(int* t, int mode);
  61. int createTree(QTree* t, char* fname, int xmin, int xmax, int ymin, int ymax, int N);
  62. int createFile(QTree* t, char* fname);
  63. int load(QTree* t, char* fname);
  64. int dialog(const char* msgs[], int N);
  65. int quadrant(int x, int y, float xmin, float xmax, float ymin, float ymax);
  66. int divide(Node* parent);
  67. int linsert(elem* item, itemList* head);
  68. char* getStr(int mode);
  69. char* makeStr(const char buf[]);
  70. int search(QTree* t, Node** node, itemList** answer, int x, int y);
  71. itemList*** traverse(Node* node, itemList*** arrptr, int* n);
  72. int showXDirectOrder(QTree* t);
  73. int showRange(QTree* t);
  74. int inRange(itemList*, int xmin, int xmax, int ymin, int ymax);
  75. int showTree(QTree* t);
  76. int treeView(Node* r, int lvl);
  77. int delNode(Node* r, int i);
  78. int timing(QTree* t);
  79.  
  80. int(*sfptr[])(QTree*) = { NULL, showXDirectOrder, showRange, showTree };
  81. int(*fptr[])(QTree*) = { NULL, dinsert, dsearch, dremove, dshow, dsave, properties, timing};
  82.  
  83. int timing(QTree* t) {
  84.     QTree testTree = { 0, NULL, NULL };
  85.     createTree(&testTree, NULL, INT_MIN, INT_MAX, INT_MIN, INT_MAX, 10);
  86.     clock_t first, last;
  87.     int n = 10, x[100000], y[100000], cnt = 400000, i, m;
  88.     srand(time(NULL));
  89.     while (n-- > 0) {
  90.         for (i = 0; i < 100000; ++i) {
  91.             x[i] = i;
  92.             y[i] = i;
  93.         }
  94.         for (i = 0; i < cnt; ) {
  95.             elem* te = (elem*)malloc(sizeof(elem));
  96.             char* info = makeStr("text");
  97.             te->x = rand();
  98.             te->y = rand();
  99.             te->info = info;
  100.             if (!insert(&testTree, te)) ++i;
  101.         }
  102.         m = 0;
  103.         first = clock();
  104.         for (i = 0; i < 100000; i++) {
  105.             itemList* ans;
  106.             Node*r = testTree.root;
  107.             search(&testTree, &r, &ans, x[i], y[i]);
  108.             if (ans) m++;
  109.         }
  110.         last = clock();
  111.         printf("%d items were found\n", m);
  112.         printf("test #%d, number of nodes = %d, time = %d\n", 10 - n, (10 - n)*cnt, last - first);
  113.     }
  114.     delTree(&testTree);
  115.     return 1;
  116. }
  117.  
  118. int delNode(Node* r, int i) {
  119.     itemList* tmp = r->itemshead.next;
  120.     while (tmp) {
  121.         free(tmp->data->info);
  122.         free(tmp->data);
  123.         itemList* next = tmp->next;
  124.         free(tmp);
  125.         tmp = next;
  126.     }
  127.     if (r->child) for (int i = 3; i >= 0; i--) delNode(&(r->child[i]), i);
  128.     if (!i) free(r);
  129.     return 0;
  130. }
  131.  
  132. int treeView(Node* r, int lvl) {
  133.     printf("\n");
  134.     for (int i = 0; i < lvl; i++) printf("\t");
  135.     printf("lvl%d [(%.0f; %.0f) - (%.0f; %.0f)] Busy %d\n", lvl, r->xmin, r->ymin, r->xmax, r->ymax, r->busy);
  136.     if (r->busy) {
  137.         itemList* tmp = r->itemshead.next;
  138.         while (tmp) {
  139.             for (int i = 0; i < lvl; i++) printf("\t");
  140.             printf("(%d; %d) %s\n", tmp->data->x, tmp->data->y, tmp->data->info);
  141.             tmp = tmp->next;
  142.         }
  143.     }
  144.     if (r->child) {
  145.         lvl++;
  146.         for (int i = 0; i < 4; i++) treeView(&r->child[i], lvl);
  147.     }
  148.     return 0;
  149. }
  150.  
  151. int inRange(itemList* item, int xmin, int xmax, int ymin, int ymax) {
  152.     int x = item->data->x, y = item->data->y;
  153.     if (x >= xmin && x <= xmax && y <= ymax && y >= ymin) return 1;
  154.     else return 0;
  155. }
  156.  
  157. int showRange(QTree* t) {
  158.     int xmin, xmax, ymin, ymax;
  159.     printf("Enter key range:\n");
  160.     printf("Min x: -->");
  161.     getInt(&xmin, -1);
  162.     printf("Max x: -->");
  163.     getInt(&xmax, -1);
  164.     printf("Min y: -->");
  165.     getInt(&ymin, -1);
  166.     printf("Max y: -->");
  167.     getInt(&ymax, -1);
  168.     if (xmin > t->root->xmax || xmax < t->root->xmin || ymin > t->root->ymax || ymax < t->root->xmin) {
  169.         printf("This area doesn't belong to the tree\n");
  170.         return 1;
  171.     }
  172.     itemList** arrptr = (itemList**)malloc(t->n * sizeof(itemList*));
  173.     int n = 0;
  174.     traverse(t->root, &arrptr, &n);
  175.     for (int i = 0; i < n; i++)
  176.         if (inRange(arrptr[i], xmin, xmax, ymin, ymax))
  177.             printf("%d\t%d\t%s\n", arrptr[i]->data->x, arrptr[i]->data->y, arrptr[i]->data->info);
  178.     return 1;
  179. }
  180.  
  181. int properties(QTree* t) {
  182.     if (!t) return 1;
  183.     printf("Busy: %d\n", t->n);
  184.     printf("Node capacity: %d\n", t->N);
  185.     printf("Filename: %s\n", t->filename);
  186.     return 1;
  187. }
  188.  
  189. itemList*** traverse(Node* node, itemList*** arrptr, int* n) {
  190.     if (node->child == NULL) {
  191.         itemList* tmp = node->itemshead.next;
  192.         while (tmp) {
  193.             (*arrptr)[*n] = tmp;
  194.             (*n)++;
  195.             tmp = tmp->next;
  196.         }
  197.         return arrptr;
  198.     }
  199.     else {
  200.         arrptr = traverse(&node->child[2], arrptr, n);
  201.         arrptr = traverse(&node->child[3], arrptr, n);
  202.         arrptr = traverse(&node->child[1], arrptr, n);
  203.         arrptr = traverse(&node->child[0], arrptr, n);
  204.     }
  205. }
  206.  
  207. int showXDirectOrder(QTree* t) {
  208.     itemList** arrptr = (itemList**)malloc(t->n * sizeof(itemList*));
  209.     int n = 0;
  210.     traverse(t->root, &arrptr, &n);
  211.     if (!n) {
  212.         printf("Table is empty\n");
  213.         return 1;
  214.     }
  215.     printf("X\tY\tInfo\n");
  216.     for (int i = 0; i < n; i++) printf("%d\t%d\t%s\n", arrptr[i]->data->x, arrptr[i]->data->y, arrptr[i]->data->info);
  217.     free(arrptr);
  218.     return 0;
  219. }
  220.  
  221. int showTree(QTree* t) {
  222.     Node* r = t->root;
  223.     treeView(r, 0);
  224.     return 1;
  225. }
  226.  
  227. int dshow(QTree* t) {
  228.     if (!t) return 1;
  229.     if (!t->n) {
  230.         printf("Tree is empty\n");
  231.         return 2;
  232.     }
  233.     int k;
  234.     do {
  235.         for (int i = 0; i < 3; i++) printf("%s\n", showmsgs[i]);
  236.         printf("Choose your destiny: -->");
  237.         getInt(&k, 1);
  238.         if (k > 3) printf("I don\'t understand you!!11!n");
  239.     } while (k > 3);
  240.     if (sfptr[k](t)) printf("Ok\n");
  241.     return 1;
  242. }
  243.  
  244. int dsearch(QTree* t) {
  245.     if (!t) return 1;
  246.     int x, y;
  247.     printf("Enter x-->");
  248.     getInt(&x, -1);
  249.     printf("Enter y -->");
  250.     getInt(&y, -1);
  251.     itemList* ans = NULL;
  252.     Node* r = t->root;
  253.     search(t, &r, &ans, x, y);
  254.     if (!ans) printf("Item not found\n");
  255.     else {
  256.         printf("X: %d\n", ans->data->x);
  257.         printf("Y: %d\n", ans->data->y);
  258.         printf("Info: %s\n", ans->data->info);
  259.     }
  260.     return 1;
  261. }
  262.  
  263. int rmv(QTree*t, int x, int y) {
  264.     Node*r = t->root;
  265.     itemList* ans = NULL;
  266.     search(t, &r, &ans, x, y);
  267.     if (!r) return 1;
  268.     if (!ans) return 1;
  269.     ans->prev->next = ans->next;
  270.     if (ans->next) ans->next->prev = ans->prev;
  271.     free(ans->data->info);
  272.     free(ans->data);
  273.     free(ans);
  274.     r->busy--;
  275.     t->n--;
  276.     return 0;
  277. }
  278.  
  279. int dremove(QTree* t) {
  280.     int x, y;
  281.     printf("Enter x -->");
  282.     getInt(&x, -1);
  283.     printf("Enter y -->");
  284.     getInt(&y, -1);
  285.     int rc = rmv(t, x, y);
  286.     printf("%s", errdel[rc]);
  287.     return 1;
  288. }
  289.  
  290. int dsave(QTree*t) {
  291.     if (!t) return 0;
  292.     int rc = save(t);
  293.     printf("%s", errsave[rc]);
  294.     return 1;
  295. }
  296.  
  297. int save(QTree* t) {
  298.     if (!t->fd) return 1;
  299.     fseek(t->fd, 0, SEEK_SET);
  300.     fwrite(&t->n, sizeof(int), 1, t->fd);
  301.     itemList** items = (itemList**)malloc(t->n * sizeof(itemList*));
  302.     int n = 0;
  303.     traverse(t->root, &items, &n);
  304.     for (int i = 0; i < n; i++) {
  305.         fwrite(&items[i]->data->x, sizeof(int), 1, t->fd);
  306.         fwrite(&items[i]->data->y, sizeof(int), 1, t->fd);
  307.         int len = strlen(items[i]->data->info) + 1;
  308.         fwrite(&len, sizeof(int), 1, t->fd);
  309.         fwrite(items[i]->data->info, sizeof(char), len, t->fd);
  310.     }
  311.     fseek(t->fd, 0, SEEK_SET);
  312.     free(items);
  313.     return 0;
  314. }
  315.  
  316. int delTree(QTree* t) {
  317.     Node* r = t->root;
  318.     delNode(r, 0);
  319.     if (t->filename) free(t->filename);
  320.     return 0;
  321. }
  322.  
  323. int linsert(elem* item, itemList* head) {
  324.     itemList *tmp = head;
  325.     itemList* newl = (itemList*)calloc(1, sizeof(itemList));
  326.     newl->data = item;
  327.     while (tmp->next) {
  328.         if (tmp->next->data->x > item->x) break;
  329.         if (tmp->next->data->x == item->x) {
  330.             if (tmp->next->data->y == item->y) return 1;
  331.             if (tmp->next->data->y > item->y) break;
  332.         }
  333.         tmp = tmp->next;
  334.     }
  335.     if (tmp->next) {
  336.         tmp->next->prev = newl;
  337.         newl->prev = tmp;
  338.         newl->next = tmp->next;
  339.         tmp->next = newl;
  340.     }
  341.     else {
  342.         tmp->next = newl;
  343.         newl->prev = tmp;
  344.     }
  345.     return 0;
  346. }
  347.  
  348. int quadrant(int x, int y, float xmin, float xmax, float ymin, float ymax) {
  349.     if (x < xmin || x > xmax || y < ymin || y > ymax) return -1;
  350.     if (x >= (xmax + xmin) / 2) {
  351.         if (y >= (ymax+ymin) / 2) return 0;
  352.         else return 1;
  353.     }
  354.     else {
  355.         if (y >= (ymax+ymin) / 2) return 3;
  356.         else return 2;
  357.     }
  358. }
  359.  
  360. int search(QTree* t, Node** node, itemList** answer, int x, int y) {
  361.     while ((*node)->child) {
  362.         int q = quadrant(x, y, (*node)->xmin, (*node)->xmax, (*node)->ymin, (*node)->ymax);
  363.         if (q == -1) return 1;
  364.         *node = &(*node)->child[q];
  365.     }
  366.     *answer = (*node)->itemshead.next;
  367.     while (*answer) {
  368.         if ((*answer)->data->x == x && (*answer)->data->y == y) return 0;
  369.         else *answer = (*answer)->next;
  370.     }
  371.     return 0;
  372. }
  373.  
  374. int insert(QTree* t, elem* e) {
  375.     if (!t) return 1;
  376.     if (!e) return 2;
  377.     if (e->x > t->root->xmax || e->x < t->root->xmin || e->y > t->root->ymax || e->y < t->root->ymin) {
  378.         free(e->info);
  379.         free(e);
  380.         return 4;
  381.     }
  382.     Node *r = t->root;
  383.     itemList* ans = NULL;
  384.     search(t, &r, &ans, e->x, e->y);
  385.     if (ans) {
  386.         free(e->info);
  387.         free(e);
  388.         return 3;
  389.     }
  390.     while (r->busy == t->N) {
  391.         divide(r);
  392.         int q = quadrant(e->x, e->y, r->xmin, r->xmax, r->ymin, r->ymax);
  393.         r = &r->child[q];
  394.     }
  395.     linsert(e, &r->itemshead);
  396.     r->busy++;
  397.     t->n++;
  398.     return 0;
  399. }
  400.  
  401. int dinsert(QTree*t) {
  402.     if (!t) return 0;
  403.     int x, y;
  404.     char* info;
  405.     printf("Enter x: ->");
  406.     getInt(&x, 1);
  407.     printf("Enter y: ->");
  408.     getInt(&y, 1);
  409.     printf("Enter info:\n");
  410.     info = getStr(1);
  411.     elem* e = (elem*)malloc(sizeof(elem));
  412.     e->x = x;
  413.     e->y = y;
  414.     e->info = info;
  415.     int rc = insert(t, e);
  416.     printf("%s\n", errins[rc]);
  417.     return 1;
  418. }
  419.  
  420. int divide(Node* parent) {
  421.     if (!parent) return 1;
  422.     parent->child = (Node*)malloc(4 * sizeof(Node));
  423.     for (int i = 0; i < 4; i++) {
  424.         parent->child[i].busy = 0;
  425.         parent->child[i].busy = 0;
  426.         parent->child[i].itemshead.data = NULL;
  427.         parent->child[i].itemshead.next = NULL;
  428.         parent->child[i].itemshead.prev = NULL;
  429.         parent->child[i].child = NULL;
  430.     }
  431.     parent->child[0].xmin = (parent->xmin + parent->xmax) / 2;
  432.     parent->child[0].xmax = parent->xmax;
  433.     parent->child[0].ymin = (parent->ymin + parent->ymax) / 2;
  434.     parent->child[0].ymax = parent->ymax;
  435.     parent->child[1].xmin = (parent->xmin + parent->xmax) / 2;
  436.     parent->child[1].xmax = parent->xmax;
  437.     parent->child[1].ymin = parent->ymin;
  438.     parent->child[1].ymax = (parent->ymin + parent->ymax) / 2;
  439.     parent->child[2].xmin = parent->xmin;
  440.     parent->child[2].xmax = (parent->xmin + parent->xmax) / 2;
  441.     parent->child[2].ymin = parent->ymin;
  442.     parent->child[2].ymax = (parent->ymin + parent->ymax) / 2;
  443.     parent->child[3].xmin = parent->xmin;
  444.     parent->child[3].xmax = (parent->xmin + parent->xmax) / 2;
  445.     parent->child[3].ymin = (parent->ymin + parent->ymax) / 2;
  446.     parent->child[3].ymax = parent->ymax;
  447.     itemList* tmp = parent->itemshead.next;
  448.     while (tmp) {
  449.         int q = quadrant(tmp->data->x, tmp->data->y, parent->xmin, parent->xmax, parent->ymin, parent->ymax);
  450.         linsert(tmp->data, &parent->child[q].itemshead);
  451.         parent->child[q].busy++;
  452.         itemList* tmp1 = tmp;
  453.         tmp = tmp->next;
  454.         free(tmp1);
  455.     }
  456.     parent->itemshead.next = NULL;
  457.     parent->busy = 0;
  458.     return 0;
  459. }
  460.  
  461. int createFile(QTree*t, char* fname) {
  462.     if (!t) return 1;
  463.     if (!fname) return 2;
  464.     fopen_s(&(t->fd), fname, "w+b");
  465.     return 0;
  466. }
  467.  
  468. int load(QTree *t, char *fname) {
  469.     if (!t) return 1;
  470.     if (!fname) return 2;
  471.     fopen_s(&t->fd, fname, "r+b");
  472.     if (!t->fd) return 3;
  473.     t->filename = fname;
  474.     int n;
  475.     fread(&n, sizeof(int), 1, t->fd);
  476.     int errs = 0;
  477.     for (int i = 0; i < n; i++) {
  478.         elem *tmp = (elem*)calloc(1, sizeof(elem));
  479.         fread(&tmp->x, sizeof(int), 1, t->fd);
  480.         fread(&tmp->y, sizeof(int), 1, t->fd);
  481.         int len;
  482.         fread(&len, sizeof(int), 1, t->fd);
  483.         char* info = (char*)malloc(len);
  484.         *info = '\0';
  485.         tmp->info = info;
  486.         fread(tmp->info, sizeof(char), len, t->fd);
  487.         if (insert(t, tmp) == 4) errs++;
  488.     }
  489.     if (errs) printf("%d points weren\'t loaded because they don\'t fit the tree\n", errs);
  490.     return 0;
  491. }
  492.  
  493.  
  494. int dload(QTree *t) {
  495.     int rc = 1, xmin, xmax, ymin, ymax, N;
  496.     char* fname = NULL;
  497.     while(rc) {
  498.         printf("Enter file name: --> ");
  499.         fname = getStr(0);
  500.         if (!fname) return 0;
  501.         printf("Enter key range:\n");
  502.         printf("Min x: -->");
  503.         getInt(&xmin, -1);
  504.         printf("Max x: -->");
  505.         getInt(&xmax, -1);
  506.         printf("Min y: -->");
  507.         getInt(&ymin, -1);
  508.         printf("Max y: -->");
  509.         getInt(&ymax, -1);
  510.         printf("N: -->");
  511.         getInt(&N, 1);
  512.         rc = createTree(t, fname, xmin, xmax, ymin, ymax, N);
  513.         printf("%s\n", errload[rc]);
  514.     }
  515. }
  516.  
  517. int createTree(QTree* t, char* fname, int xmin, int xmax, int ymin, int ymax, int N) {
  518.     if (!t) return 1;
  519.     //if (!fname) return 2;
  520.     if (N < 1) return 3;
  521.     if (xmin > xmax) {
  522.         printf("Minimal X is greater than maximal one, it\'s interesting... They\'ll be swapped\n");
  523.         int tmp = xmin;
  524.         xmin = xmax;
  525.         xmax = tmp;
  526.     }
  527.     if (ymin > ymax) {
  528.         printf("Minimal Y is greater than maximal one, it\'s interesting... They\'ll be swapped\n");
  529.         int tmp = ymin;
  530.         ymin = ymax;
  531.         ymax = tmp;
  532.     }
  533.     Node* root = (Node*)malloc(1 * sizeof(Node));
  534.     t->root = root;
  535.     t->N = N;
  536.     t->n = 0;
  537.     t->filename = fname;
  538.     t->root->xmax = xmax;
  539.     t->root->xmin = xmin;
  540.     t->root->ymin = ymin;
  541.     t->root->ymax = ymax;
  542.     t->root->busy = 0;
  543.     t->root->itemshead.data = NULL;
  544.     t->root->itemshead.next = NULL;
  545.     t->root->itemshead.prev = NULL;
  546.     t->root->child = NULL;
  547.     if (fname) if (load(t, fname)) createFile(t, fname);
  548.     //if (!(fopen_s(&(t->fd), fname, "w+b"))) t->root = NULL;
  549.     return 0;
  550. }
  551.  
  552. char* makeStr(const char buf[]) {
  553.     char *s = (char*)malloc(strlen(buf) + 1);
  554.     *s = '\0';
  555.     strcat(s, buf);
  556.     return s;
  557. }
  558.  
  559. int dialog(const char* msgs[], int N) {
  560.     int rc;
  561.     do {
  562.         for (int i = 0; i < N; ++i) puts(msgs[i]);
  563.         puts("Make your choice: --> ");
  564.         if (!getInt(&rc, 0)) rc = 0;
  565.         if (rc >= 0 && rc < N) continue;
  566.         puts("I don't understand you. Please try again.");
  567.     } while (rc < 0 || rc >= N);
  568.     return rc;
  569. }
  570.  
  571. int getInt(int *t, int mode = -1) {
  572.     int r;
  573.     do {
  574.         r = scanf_s("%d", t);
  575.         if (r == 1) {
  576.             if (mode == -1) return r;
  577.             if (mode == 0) {
  578.                 if (t >= 0) return r;
  579.                 else {
  580.                     printf("Input is incorrect. You should enter a non-negative integer. Try again\n");
  581.                     scanf_s("%*[^\n]");
  582.                     continue;
  583.                 }
  584.             }
  585.             else if (mode == 1) {
  586.                 if (t > 0) return r;
  587.                 else {
  588.                     printf("Input is incorrect. You should enter a positive integer. Try again\n");
  589.                     scanf_s("%*[^\n]");
  590.                     continue;
  591.                 }
  592.             }
  593.             else return r;
  594.         }
  595.         printf("Input is incorrect. You should enter an integer. Try again.\n");
  596.         scanf_s("%*[^\n]");
  597.     } while (1);
  598. }
  599.  
  600. char *getStr(int mode = 1) {
  601.     char *ptr = (char*)malloc(sizeof(char));
  602.     char buf[81];
  603.     int n, len = 0;
  604.     *ptr = '\0';
  605.     if (mode) scanf_s("%*c");
  606.     do {
  607.         n = scanf_s("%80[^\n]", buf, 81);
  608.         if (n < 0) {
  609.             free(ptr);
  610.             ptr = NULL;
  611.             continue;
  612.         }
  613.         if (n == 0) scanf_s("%*c");
  614.         else {
  615.             len += strlen(buf);
  616.             ptr = (char*)realloc(ptr, len + 1);
  617.             strcat(ptr, buf);
  618.         }
  619.     } while (n > 0);
  620.     return ptr;
  621. }
  622.  
  623. int main() {
  624.     QTree t = { 0, NULL, NULL };
  625.     int rc;
  626.     if (!dload(&t)) return 1;
  627.     while (rc = dialog(msgs, NMsgs)) if (!fptr[rc](&t)) break;
  628.     dsave(&t);
  629.     puts("Program finished");
  630.     fclose(t.fd);
  631.     delTree(&t);
  632.     return 0;
  633. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top