Advertisement
Guest User

Untitled

a guest
May 27th, 2015
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.83 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<stdbool.h>
  5. #include<errno.h>
  6. #include <ctype.h>
  7.  
  8. typedef struct Measurements {
  9.  int bust, waist, hip;
  10.  
  11.  } Measurements;
  12. typedef struct Contestant {
  13.  char *firstName;
  14.  char *lastName;
  15.  char *interests;
  16.  int age;
  17.  int height;
  18.  Measurements bwh;
  19. } Contestant;
  20.  
  21.  
  22. typedef struct Pair {
  23.  int id;
  24.  Contestant *con;
  25.  } Pair;
  26.  
  27.  typedef struct Stack {
  28.  Pair *data;
  29.  int n;
  30.  int size;
  31.  int id;
  32.  } Stack;
  33.  
  34.  
  35.  void* myrealloc (void *ptr, size_t size) {
  36.  void *res = realloc(ptr, size);
  37. if (res == NULL && size != 0) {
  38. fprintf(stderr, "myrealloc: unable to allocate %zd bytes\n", size);
  39. exit(EXIT_FAILURE); }
  40. return res;
  41. }
  42. /**/
  43. void* mymalloc (size_t size) {
  44.  void *res = malloc(size);
  45. if (res == NULL) {
  46. fprintf(stderr, "mymalloc: unable to allocate %zd bytes\n ", size);
  47. exit(EXIT_FAILURE);
  48. }
  49. return res;
  50. }
  51.  
  52.  
  53.  
  54. void printContestant (const struct Contestant *con) {
  55. printf("First Name: %s\n", con->firstName);
  56. printf("Last Name: %s\n", con->lastName);
  57. printf("Interests: %s\n", con->interests);
  58. printf("Age: %d\n", con->age);
  59. printf("Height: %d\n", con->height);
  60. printf("Measurments: %d %d %d\n", con->bwh.bust,con->bwh.waist,con->bwh.hip);
  61. }
  62.  
  63. void destroyContestant (Contestant *con) {
  64.  if (con == NULL) return;
  65.  free(con->firstName);
  66.  free(con->lastName);
  67.  free(con->interests);
  68.  free(con);
  69.  }
  70.  
  71.  
  72.  
  73.  Stack* newStack ();
  74.  void emptyStack (Stack *stack);
  75.  void destroyStack (Stack *stack);
  76.  void insertContestant (Stack *stack, Contestant *con);
  77.  void removeContestant (Stack *stack, int ix);
  78.  bool removeContestantId (Stack *stack, int id);
  79.  
  80.  Stack* newStack () {
  81.  Stack *stack = (Stack *)mymalloc(sizeof(*stack));
  82.  int initSize = 32;
  83.  stack->data = (Pair *)mymalloc(sizeof(*stack->data) * initSize);
  84.  stack->n = 0;
  85.  stack->size = initSize;
  86.  stack->id = 0;
  87.  return stack;
  88.  }
  89.  
  90.  void emptyStack (Stack *stack) {
  91.  Pair *p = stack->data;
  92.  int i,n = stack->n;
  93.  for ( i = 0; i < n; i++) {
  94.  destroyContestant(p[i].con);
  95.  }
  96.  stack->n = 0;
  97.  }
  98.  
  99.  void destroyStack (Stack *stack) {
  100.  if (stack == NULL) return;
  101.  emptyStack(stack);
  102.  free(stack->data);
  103.  free(stack);
  104.  }
  105.  
  106.  void insertContestant (Stack *stack, Contestant *con) {
  107.  if (stack->size == stack->n) {
  108.  stack->size *= 2;
  109.  stack->data = (Pair*)myrealloc(stack->data, stack->size);
  110.  }
  111.  Pair *p = &stack->data[stack->n];
  112.  p->id = stack->id;
  113.  p->con = con;
  114.  stack->n++;
  115.   stack->id++;
  116.  }
  117.  
  118.  void removeContestant (Stack *stack, int ix) {
  119.   Contestant *con = stack->data[ix].con;
  120.  destroyContestant(con);
  121.  int i,n = stack->n;
  122.  Pair *p = stack->data;
  123.  for (i = ix + 1; i < n; i++) {
  124.  p[i - 1] = p[i];
  125.  }
  126.  stack->n--;
  127.  }
  128.  
  129.  bool removeContestantId (Stack *stack, int id) {
  130.  bool flag = false;
  131.  int ix = -1;
  132.  Pair *p = stack->data;
  133.  int i,n = stack->n;
  134.  
  135.  for (i = 0; i < n; i++) {
  136.  if (p[i].id == id) {
  137.  flag = true;
  138.  ix = i;
  139.  break;
  140.  }
  141.  }
  142.  if (flag) removeContestant(stack, ix);
  143.  return flag;
  144.  }
  145.  
  146.  void printPair (const Pair *pair) {
  147.  printf("ID: %d\n", pair->id);
  148.  printContestant(pair->con);
  149.  }
  150.  
  151.  void printContestantArray (Pair *xs, int n) {
  152.       int i;
  153.  for ( i = 0; i < n; i++) {
  154.  printPair(xs + i);
  155.  printf("\n");
  156.  }
  157.  }
  158.  
  159.  
  160.  char* stripSpaces (const char *str) {
  161.   const char *s = str;
  162.   while (isspace(*s) && *s != '\0') s++;
  163.   const char *e = str;
  164.   while (*e != '\0') e++;
  165.   if (e == s) {
  166.     char *result = (char*)mymalloc(sizeof(*result));
  167.     *result = '\0';
  168.     return result;
  169.   }
  170.   e--;
  171.   while (isspace(*e)) e--;
  172.   int n = e - s + 1;
  173.   char *result = (char*)mymalloc((n + 1) * sizeof(*result));
  174.   memcpy(result, s, n);
  175.   result[n] = '\0';
  176.   return result;
  177. }
  178.  
  179. bool hasEndl (const char *str) {
  180.   while (*str != '\0' && *str != '\n') str++;
  181.   return *str == '\n';
  182. }
  183.  
  184. char* readLine (FILE *file) {
  185.   char *str = NULL;
  186.   int size = 32;
  187.   int n = 0;
  188.   while (true) {
  189.     str = (char*)myrealloc(str, size);
  190.     if (fgets(str + n, size - n, file) == NULL) {
  191.       if (n != 0 && feof(file)) return str;
  192.       free(str);
  193.       return NULL;
  194.     }
  195.     if (hasEndl(str + n)) return str;
  196.     n = size - 1;
  197.     size *= 2;
  198.   }
  199. }
  200.  
  201. char* readLineS (FILE *file) {
  202.   char *s = readLine(file);
  203.   if (s == NULL) return NULL;
  204.   char *r = stripSpaces(s);
  205.   free(s);
  206.   if (*r == '\0') {
  207.     free(r);
  208.     return NULL;
  209.   }
  210.   return r;
  211. }
  212.  
  213. bool readIntLine (int *result) {
  214.   char *s = readLine(stdin);
  215.   if (s == NULL) return false;
  216.   int n = 0;
  217.   bool flag = true;
  218.   if (sscanf(s, "%d %n", result, &n) != 1 || s[n] != '\0') flag = false;
  219.   free(s);
  220.   return flag;
  221. }
  222. bool readDoubleLine (double *result) {
  223.   char *s = readLine(stdin);
  224.   if (s == NULL) return false;
  225.   int n = 0;
  226.   bool flag = true;
  227.   if (sscanf(s, "%ld %n", result, &n) != 1 || s[n] != '\0') flag = false;
  228.   free(s);
  229.   return flag;
  230. }
  231.  
  232.  
  233.  
  234.  Contestant* inputContestant () {
  235.   Contestant *result = (Contestant*)mymalloc(sizeof(*result));
  236.   result->firstName = NULL;
  237.   result->lastName = NULL;
  238.   result->interests = NULL;
  239.   printf("Введите данные участнике\n");
  240.   printf("Имя: ");
  241.   result->firstName = readLineS(stdin);
  242.   if (result->firstName == NULL) goto fail;
  243.   printf("Фамилия: ");
  244.   result->lastName = readLineS(stdin);
  245.   if (result->lastName == NULL) goto fail;
  246.   printf("Интересы: ");
  247.   result->interests = readLineS(stdin);
  248.   if (result->interests == NULL) goto fail;
  249.   printf("Возраст: ");
  250.   if (!readIntLine(&result->age)|| result->age < 0) goto fail;
  251.   printf("Рост: ");
  252.   if (!readIntLine(&result->height) || result->height < 0) goto fail;
  253.   printf("Бюст: ");
  254.  if (!readIntLine(&result->bwh.bust) || result->bwh.bust < 0) goto fail;
  255.   printf("Талия: ");
  256.  if (!readIntLine(&result->bwh.waist) || result->bwh.waist < 0) goto fail;
  257.   printf("Бедро: ");
  258.  if (!readIntLine(&result->bwh.hip) || result->bwh.hip < 0) goto fail;
  259.  
  260.   return result;
  261.  fail:
  262.   fprintf(stderr, "Ошибка ввода\n");
  263.   destroyContestant(result);
  264.  
  265.   return NULL;
  266. }
  267. void stripContestant (Contestant *con) {
  268.   char *lastName = con->lastName;
  269.   char *firstName = con->firstName;
  270.   char *interests = con->interests;
  271.  
  272.   con->firstName = stripSpaces(firstName);
  273.   con->lastName = stripSpaces(lastName);
  274.   con->interests = stripSpaces(interests);
  275.  
  276.   free(lastName);
  277.   free(firstName);
  278.   free(interests);
  279. }
  280.  
  281.  
  282. Contestant* readContestantLine (const char *str) {
  283.  int len = strlen(str);
  284.  Contestant *con = (Contestant*)mymalloc(sizeof(*con));
  285.  con->firstName = (char*)mymalloc((len + 1) * sizeof(*con->firstName));
  286.  con->lastName = (char*)mymalloc((len + 1) * sizeof(*con->lastName));
  287.  con->interests = (char*)mymalloc((len + 1) * sizeof(*con->interests));
  288.  int n;
  289.  int res = sscanf(str, " %[^#] # %[^#] # %[^#] # %d # %d # %d # %d # %d %n",
  290.  con->firstName, con->lastName, con->interests,
  291.  &con->age, &con->height, &con->bwh.bust,&con->bwh.waist,&con->bwh.hip, &n);
  292.  if (res != 8 || str[n] != '\0') goto fail;
  293.  
  294.  stripContestant(con);
  295.  return con;
  296.  fail:
  297.  destroyContestant(con);
  298.  return NULL;
  299.  }
  300.  
  301.  bool isEmptyString (const char *str) {
  302.  while (isspace(*str) && *str != '\0') str++;
  303.  return *str == '\0';
  304.  }
  305.  
  306.  void readFile (const char *path, Stack *stack) {
  307.  emptyStack(stack);
  308.  FILE *file = fopen(path, "r");
  309.  if (file == NULL) {
  310.  fprintf(stderr, "%s: %s\n", path, strerror(errno));
  311.  printf("Ошибка чтения\n");
  312.  return;
  313.  }
  314.  int line = 0;
  315.  Contestant *con = NULL;
  316.  char *str = NULL;
  317.  for (;;) {
  318.  line++;
  319.  free(str);
  320.  str = readLine(file);
  321.  if (str == NULL) break;
  322.  if (isEmptyString(str)) continue;
  323.  con = readContestantLine(str);
  324.  if (con == NULL) break;
  325.  insertContestant(stack, con);
  326.  }
  327.  free(str);
  328.  if (ferror(file)) {
  329.  
  330.  fprintf(stderr, "%s:%d: %s\n", path, line, strerror(errno));
  331.  emptyStack(stack);
  332.  printf("Ошибка чтения\n");
  333.  clearerr(file);
  334.  } else if (str != NULL && con == NULL) {
  335.  fprintf(stderr, "%s:%d: Неправильный формат записи\n", path, line);
  336.  emptyStack(stack);
  337.  printf("Ошибка чтения\n");
  338.  } else {
  339.  printf("Файл успешно прочитан, всего %d записей с книгами\n", stack->n);
  340.  }
  341.  if (fclose(file) != 0) {
  342.  fprintf(stderr, "%s: %s\n", path, strerror(errno));
  343.  }
  344.  }
  345.  
  346.  void doReadFile (Stack *stack) {
  347.  printf("Чтения базы данных блюд из файла\n");
  348.  printf("Введите название файла: ");
  349.  char *s = readLineS(stdin);
  350.  if (s == NULL) {
  351.  printf("Ошибка ввода\n");
  352.  return;
  353.  }
  354.  readFile(s, stack);
  355.  free(s);
  356.  }
  357.  
  358.  
  359.  
  360.  void writeContestantLine (FILE *file, Contestant *con) {
  361.  fprintf(file, "%s # %s # %s # %d # %d # %d # %d # %d\n",
  362.  con->firstName, con->lastName, con->interests,
  363.  con->age, con->height, con->bwh.bust,con->bwh.waist,con->bwh.hip);
  364.  }
  365.  
  366.  void writeFile (const char *path, Stack *stack) {
  367.  FILE *file = fopen(path, "w");
  368.  if (file == NULL) {
  369.  
  370.  
  371.  fprintf(stderr, "%s: %s\n", path, strerror(errno));
  372.  return;
  373.  }
  374.  
  375.  Pair *p = stack->data;
  376.  int i,n = stack->n;
  377.  for (i = 0; i < n; i++) {
  378.  writeContestantLine(file, p[i].con);
  379.  if (ferror(file)) {
  380.  fprintf(stderr, "%s:%d: %s\n", path, i, strerror(errno));
  381.  clearerr(file);
  382.  break;
  383.  }
  384.  }
  385.   if (fclose(file) != 0) {
  386.  fprintf(stderr, "%s: %s\n", path, strerror(errno));
  387.  }
  388.  }
  389.  
  390.  void doPrintContestant (Stack *stack) {
  391.   printContestantArray(stack->data, stack->n);
  392. }
  393.  
  394. void doRemoveContestant (Stack *stack) {
  395.   int id;
  396.   printf("Введите ID участника, которого нужно удалить: ");
  397.   if (!readIntLine(&id)) {
  398.     printf("Ошибка ввода\n");
  399.     return;
  400.   }
  401.   if (!removeContestantId(stack, id)) {
  402.     printf("Участника с таким  ID нет в списке\n");
  403.   }
  404. }
  405.  
  406.  void doWriteFile (Stack *stack) {
  407.  printf("Запись базы данных участников в файл\n");
  408.  printf("Введите название файла: ");
  409.  char *s = readLineS(stdin);
  410.  if (s == NULL) {
  411.  printf("Ошибка ввода\n");
  412.  return;
  413.  }
  414.  writeFile(s, stack);
  415.  free(s);
  416.  }
  417.    typedef int (*Compare) (const void *a, const void *b);
  418.  
  419.  Pair* mySort (Pair *p, int n, int (*f) (Pair *a, Pair *b)) {
  420.  Pair *r = (Pair*)mymalloc(n * sizeof(*r));
  421.  memcpy(r, p, n * sizeof(*r));
  422.  qsort(r, n, sizeof(*r), (Compare) f);
  423.  return r;
  424.  }
  425.  
  426.  int compareName (Pair *a, Pair *b) {
  427.  //int result = strcmp(a->con->firstName, b->con->firstName) + strcmp(a->con->lastName,b->con->lastName);
  428.  int result = strcmp(a->con->lastName, b->con->lastName);
  429. if (result != 0) return result;
  430. result = strcmp(a->con->firstName, b->con->firstName);
  431.  
  432.  return result;
  433.  }
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  void doSortName (Stack *stack) {
  442. Pair *xs = mySort(stack->data, stack->n, compareName);
  443.  printf("Список участников отсортированный по названию: \n\n");
  444.  printContestantArray(xs, stack->n);
  445.  free(xs);
  446.  }
  447.  
  448. void doInputContestant (Stack *stack) {
  449.   Contestant *con = inputContestant();
  450.   insertContestant(stack, con);
  451. }
  452.  
  453. void  selectBWH(Pair* p,int n,int bustmin,int bustmax,int waistmin,int waistmax,int hipmin,int hipmax)
  454. {
  455.      for(int i=0;i<n;i++) {
  456.         if((p+i)->con->bwh.bust > bustmin && (p+i)->con->bwh.bust < bustmax && (p+i)->con->bwh.waist > waistmin && (p+i)->con->bwh.waist < waistmax && (p+i)->con->bwh.hip > hipmin && (p+i)->con->bwh.hip < hipmax ) {
  457.         printPair(p+i);
  458.         }
  459.      }
  460. }
  461. void doBWHContestant (Stack *stack) {
  462.      int bustmin,bustmax,waistmin,waistmax,hipmin,hipmax,i;
  463.  
  464.     printf("Bust min:");
  465.  
  466.     if(!readIntLine(&bustmin))
  467.     {
  468.     perror("Ошибка чтения!");
  469.     exit(1);
  470.     }
  471.  
  472.     printf("Bust max:");
  473.  
  474.     if(!readIntLine(&bustmax))
  475.     {
  476.     perror("Ошибка чтения!");
  477.     exit(1);
  478.     }
  479.     printf("Waist min:");
  480.  
  481.     if(!readIntLine(&waistmin))
  482.     {
  483.     perror("Ошибка чтения!");
  484.     exit(1);
  485.     }
  486.  
  487.     printf("Waist max:");
  488.  
  489.     if(!readIntLine(&waistmax))
  490.     {
  491.     perror("Ошибка чтения!");
  492.     exit(1);
  493.     }
  494.  
  495.     printf("Hip min:");
  496.  
  497.     if(!readIntLine(&hipmin))
  498.     {
  499.     perror("Ошибка чтения!");
  500.     exit(1);
  501.     }
  502.  
  503.     printf("Hip max:");
  504.  
  505.     if(!readIntLine(&hipmax))
  506.     {
  507.     perror("Ошибка чтения!");
  508.     exit(1);
  509.     }
  510.     Pair* p = stack->data;
  511.     int n= stack->n;
  512.         selectBWH(p,n,bustmin,bustmax,waistmin,waistmax,hipmin,hipmax);
  513.  
  514. }
  515.  
  516. void selectHeighContestant(Pair* p,int n, int height)
  517. {
  518.      for(int i=0;i<n;i++) {
  519.         if((p+i)->con->height > height ) {
  520.         printPair(p+i);
  521.         }
  522.      }
  523.    
  524. }
  525.  
  526. void doHeightContestant(Stack* stack)
  527. {
  528.        
  529.     printf("Рост: ");
  530.     int height;
  531.     if (!readIntLine(&height)) {
  532.         fprintf(stderr, "Ошибка ввода\n");
  533.         return;
  534.     }
  535.    
  536.    
  537.     printf("\n");
  538.     Pair* p = stack->data;
  539.     int n= stack->n;
  540.     selectHeighContestant(p,n,height);
  541.     printf("\n");
  542.    
  543. }
  544.  
  545. Pair* filterInterests (const Pair *xs, int n, const char *str, int *m) {
  546.   int k = 0, s = 32;
  547.   Pair *p = (Pair*)mymalloc(s * sizeof(*p));
  548.   for (int i = 0; i < n; i++) {
  549.     if (strstr(xs[i].con->interests, str) != NULL) {
  550.       if (k == s) {
  551.         s *= 2;
  552.         p = (Pair*)myrealloc(p, s * sizeof(*p));
  553.       }
  554.       p[k] = xs[i];
  555.       k++;
  556.     }
  557.   }
  558.   *m = k;
  559.   return p;
  560. }
  561.  
  562. void doFilterInterests (Stack *stack) {
  563.   printf("Выбрать участников по интересам\n");
  564.   printf("Введите один из интересов: ");
  565.   char *s = NULL;
  566.   Pair *xs = NULL;
  567.   int n;
  568.   s = readLineS(stdin);
  569.   if (s == NULL) {
  570.     printf("Ошибка чтения\n");
  571.     return;
  572.   }
  573.   xs = filterInterests(stack->data, stack->n, s, &n);
  574.   printf("Результаты (всего %d):\n\n", n);
  575.   printContestantArray(xs, n);
  576.   free(s);
  577.   free(xs);
  578. }
  579.  
  580.  
  581.  void doNothing (Stack *stack) {
  582. }
  583.  typedef void (*Command) (Stack *stack);
  584.  
  585.  typedef struct CommandPair {
  586.  int code;
  587.  char *description;
  588.  Command func;
  589.  } CommandPair;
  590.  
  591.  CommandPair commands[] = {
  592.  {'r', "прочитать список участников из файла", doReadFile},
  593.  {'w', "записать список участников в файл", doWriteFile},
  594.  {'i', "добавить нового участника", doInputContestant},
  595.  {'d', "удалить из списка участника по его ID", doRemoveContestant},
  596.  {'p', "вывести список участников", doPrintContestant},
  597.  {'s', "сортировка по фамилии, имени", doSortName},
  598.  {'t', "поиск по интересам", doFilterInterests},
  599.  {'y', "вывод информации об участниках с ростом выше заданного", doHeightContestant},
  600.  {'f', "вывод информации об участниках с заданными пропорциями тела, указывается нижним и верхним пределами", doBWHContestant},
  601.  {'h', "вывести это сообщение", doNothing},
  602.  {'q', "выйти из программы", doNothing},
  603.  
  604.  };
  605.  
  606.  int prompt () {
  607.  int code = EOF;
  608.  printf("Введите команду (h для справки): ");
  609.  char *s = readLineS(stdin);
  610.  if (s == NULL) return EOF;
  611.  if (strlen(s) == 1) code = s[0];
  612.  free(s);
  613.  return code;
  614.  }
  615.  
  616.  void printHelp () {
  617.  int i,len = sizeof(commands) / sizeof(commands[0]);
  618.  for (i = 0; i < len; i++) {
  619.  printf("%c: %s\n", commands[i].code, commands[i].description);
  620.  }
  621.  }
  622.  
  623.  void dispatchCommand (Stack *stack, int code) {
  624.  int i,len = sizeof(commands) / sizeof(commands[0]);
  625.  for (i = 0; i < len; i++) {
  626.  if (code == commands[i].code) {
  627.  commands[i].func(stack);
  628.  return;
  629.  }
  630.  }
  631.  printf("Неизвестная команда\n");
  632.  }
  633.  
  634.  int main () {
  635.  Stack *stack = newStack();
  636.  bool flag = true;
  637.  char code;
  638.  do {
  639.  code = prompt();
  640.  switch (code) {
  641.  case 'h':
  642.  printHelp();
  643.  break;
  644.  case 'q':
  645.  flag = false;
  646.  break;
  647.  case EOF:
  648.  if (feof(stdin)) flag = false;
  649.  break;
  650.  default:
  651.  dispatchCommand(stack, code);
  652.  break;
  653.  }
  654.  } while (flag);
  655.  destroyStack(stack);
  656.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement