Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.39 KB | None | 0 0
  1. /*
  2.  * 1) Вы протестировали программу. Все хорошо работало.
  3.  * 2) Вам не понравилось то, что у меня слишком большой код в main. Я разбил на функции, которые делают основные действия.
  4.  * 3) Также я использовал функцию gets. Минус ее использования в том, что я могу начать считывать строку, размер которой больше буфера.
  5.  *  В таком случае поведение не определено. Например, у меня выкидывается ошибка "Segmentation fault", а у моих одногруппников буфер начинал перезаписываться.
  6.  * 4) Поэтому нужно использовать функцию fgets, которая принимает в качестве аргумента максимальное кол-во считываемых символов.
  7.  *  Эта функция возвращает указатель на считанную строку. Если был достигнут конец файла, и не было считано ни одного байта, то возвращается NULL.
  8.  *  Также NULL вернется, если произошла ошибка чтения файла. Например, подали указатель на файл, не открытый для чтения.
  9.  *  Функция перестает считывать строку в трех случаях:
  10.  *      1. Закончилась строка символом переноса. В этом случае возвращается строка с символом переноса в конце, так как этот символ последний считанный. После переноса нулевой символ.
  11.  *      2. Если считано (n - 1) символов. Не n, потому что оставляется место под нулевой символ.
  12.  *      3. Достигнут конец файла. К считанной строке добавляется нулевой символ.
  13.  */
  14.  
  15. #include <errno.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18.  
  19. const int max_size = 100;
  20.  
  21. typedef struct List_entry {
  22.     char *string;
  23.     struct List_entry *next;
  24. } List_entry;
  25.  
  26. typedef struct List {
  27.     List_entry *first;
  28.     List_entry *last;
  29. } List;
  30.  
  31. List_entry* get_new_list_entry(char *new_string);
  32. void destroy_list(List *list);
  33. void print(List list);
  34. List_entry* push_back(List *list, List_entry *entry);
  35.  
  36.  
  37. //// Функция по-прежнему огромная, разделяйте дальше.
  38. int main(int argc, char *argv[]) {
  39.     // Объявления списка, указателя на новый элемент списка и буффера под новую строку.
  40.     List list;
  41.     list.first = NULL;
  42.     list.last = NULL;
  43.     List_entry *new_list_entry = NULL;
  44.     char new_string[max_size];
  45.  
  46.     // Бесконечный цикл, выход из которого произойдет, когда первый символ считанной строки будет '.'
  47.  
  48.     ////Заведите макрос или именованную константу, которая будет обозначать условие, до которого исполняется ваш цикл.
  49.     while(1) {
  50.         // Считываем строку (или первые (mas_size - 1) символов строки. В этом случае на следующей итерации цикла продолжим считывать эту строку)
  51.        
  52.         //// Исходя из вашего объяснения пользователь не сможет ввести все 100 значащих символов для него. Если вам нужно дополнительное место под 0, то заводите массив сооветствующего размера.
  53.         //// Надо исходить из человеческих требований, пользователь не должен учитывать нюансы устройства строк.
  54.         if (fgets(new_string, max_size, stdin) == NULL) {
  55.             perror("Error of fgets");
  56.             return EXIT_FAILURE;
  57.         }
  58.  
  59.         // Проверка на конец считывания
  60.  
  61.         //// Заведите именованную константу, которая будет отражать смысл этого сравнения. Код должен описывать себя сам.
  62.         if (new_string[0] == '.') {
  63.             break;
  64.         }
  65.  
  66.         //// Логику создания элемента списка по строке и добавление этого элемента в список имеет смысл объединить в одну функцию: можно передавать список и строку в качестве параметров.
  67.  
  68.         // Создаем новый элемент списка
  69.         new_list_entry = get_new_list_entry(new_string);
  70.         if (new_list_entry == NULL) {
  71.             return EXIT_FAILURE;
  72.         }
  73.  
  74.         // Добавляем новый элемент в список
  75.         if (push_back(&list, new_list_entry) == NULL) {
  76.             //// Куда производится печать ошибки? Объяснить, что не так и исправить.
  77.             printf("Error of a pushing back the element to the list\n");
  78.             return EXIT_FAILURE;
  79.         }
  80.     }
  81.     // Выводим список
  82.     print(list);
  83.     // Освобождаем память
  84.     destroy_list(&list);
  85.  
  86.     return EXIT_SUCCESS;
  87. }
  88.  
  89. List_entry* get_new_list_entry(char *new_string) {
  90.     // Выделяем память под новый элемент списка
  91.     List_entry *new_list_entry = (List_entry*) malloc(sizeof(List_entry));
  92.     if (new_list_entry == NULL) {
  93.         perror("Error of an allocation memory for (List_entry)");
  94.         return NULL;
  95.     }
  96.     new_list_entry->next = NULL;
  97.  
  98.     // Выделяем память под строку и инициализируем ее полученным параметром
  99.     new_list_entry->string = (char*) malloc(strlen(new_string) + 1);
  100.     if (new_list_entry->string == NULL) {
  101.         //// Текст должен содержать смысл и контекст, в котором произошла ошибка. Объяснить как работает perror. Тут явное непонимание.
  102.         perror("Error of an allocation memory for (char*)");
  103.         free(new_list_entry);
  104.         return NULL;
  105.     }
  106.     strcpy(new_list_entry->string, new_string);
  107.  
  108.     return new_list_entry;
  109. }
  110.  
  111. void destroy_list(List *list) {
  112.     if (list == NULL) {
  113.         return;
  114.     }
  115.  
  116.     List_entry *entry = list->first;
  117.     List_entry *buffer_entry;
  118.  
  119.     while (entry != NULL) {
  120.         buffer_entry = entry->next;
  121.         free(entry->string);    //
  122.         free(entry);            //
  123.         entry = buffer_entry;
  124.     }
  125. }
  126.  
  127. void print(List list) {
  128.     //// Что если вам передали NULL список? Исправить код.
  129.     List_entry *entry = list.first;
  130.  
  131.     while (entry != NULL) {
  132.         printf("%s", entry->string);
  133.         entry = entry->next;
  134.     }
  135. }
  136.  
  137. List_entry* push_back(List *list, List_entry *entry) {
  138.     if (entry == NULL) {
  139.         return NULL;
  140.     }
  141.  
  142.     if (list == NULL) {
  143.         return entry;
  144.     }
  145.  
  146.     if (list->first == NULL) {
  147.         list->first = entry;
  148.         list->last = entry;
  149.         return entry;
  150.     }
  151.     list->last->next = entry;
  152.     list->last = entry;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement