Вывести из файла все русские слова по алфавиту, начинающихся с гласной - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здраствуйте. Дано текстовый файл.за один просмотр файла вывести его содержание в следующем порядке: сначала все русские слова по алфавиту, начинающихся с гласной, и количество их вхождений в файл, а затем аналогичные данные о словах, начинающихся с гласной.

Решение задачи: «Вывести из файла все русские слова по алфавиту, начинающихся с гласной»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. typedef struct node_t
  6. {
  7.    char* pstr;          // Указатель на слово
  8.    size_t length;       // Длина слова
  9.    size_t count;        // Количество слов
  10.    struct node_t* next; // Следующий узел
  11. }  TNode;
  12.  
  13. //-----------------------------------------------------------------------------
  14. // Функция меняет верхний регистр русских букв на ничжний
  15. char ToLower(char c)
  16. {
  17.    if (('А' <= c) && (c <= 'П'))
  18.    {
  19.       c += 32;
  20.    }
  21.    else if (('Р' <= c) && (c <= 'Я'))
  22.    {
  23.       c += 80;
  24.    }
  25.    else if ('Ё' == c)
  26.    {
  27.       c = 'ё';
  28.    }
  29.  
  30.    return c;
  31. }
  32. //-----------------------------------------------------------------------------
  33. // Функция определяет является ли символ буквой русского алфавита
  34. int IsAlpha(char c)
  35. {
  36.    return ((('А' <= c) && (c <= 'п') )||
  37.            (('р' <= c) && (c <= 'ё')));
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Функция сравнивает 2 строки заданной длины.
  41. // Ориентирована на русский алфавит. Сравнение регистронезависимое.
  42. int StrNCmp(const char* a, size_t lenA, const char* b, size_t lenB)
  43. {
  44.    // Берём минимальную из длин
  45.    size_t len = (lenA < lenB) ? lenA : lenB;
  46.    int result = 0;
  47.    int i;
  48.  
  49.    // Выполняем пока не достигнем минимальной длины
  50.    // или пока не найдём различия
  51.    for (i = 0; (i < len) && (result == 0); ++i)
  52.    {
  53.       result = ToLower(a[i]) - ToLower(b[i]);
  54.    }
  55.  
  56.    // Если различий небыло, тогда пытаеся наёти
  57.    // различия в длине
  58.    if (result == 0)
  59.    {
  60.       result = lenA - lenB;
  61.    }
  62.  
  63.    return result;
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Находит в заданной строке слово на русском языке.
  67. // В begin передаётся указатель на начало слова, а end - конец
  68. int GetWord(char* text, char** begin, char** end)
  69. {
  70.    // Перебирваем символы в строке пока не встретим
  71.    // русскую букву (ну или пока текст не закончится)
  72.    for (; *text && !IsAlpha(*text); ++text) { ; }
  73.  
  74.    *begin = text;
  75.  
  76.    // Перебирваем символы в строке пока встречаются
  77.    // русские буквы
  78.    for (; *text && IsAlpha(*text); ++text) { ; }
  79.  
  80.    *end = text;
  81.  
  82.    // Возвращаем длину найденного слова
  83.    return *end - *begin;
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Функция добавляет в список новое слово не нарушая порядок сортировки списка.
  87. // Если такое слово уже встречается, то значение count узла просто инкрементируется.
  88. TNode* PushWithSortAndCount(TNode** list, char* pstr, size_t length)
  89. {
  90.    // Временно создаём самый верхний узел.
  91.    // Создаётся для упрощения дальнейшего алгоритма
  92.    TNode* head = (TNode*) malloc(sizeof(TNode));
  93.    TNode* cur = head;
  94.    TNode* node;
  95.    int cmp = 1;
  96.    head->next = *list;
  97.  
  98.    // Ищем мето, куда можно пристроить новое слово.
  99.    // Если cmp будет равно 0, то это означает, что такое
  100.    // слово уже есть
  101.    for (; cur->next &&
  102.           ((cmp = StrNCmp(cur->next->pstr, cur->next->length, pstr, length)) < 0)
  103.         ; cur = cur->next) { ; }
  104.  
  105.    // Если слово не повторяется, то создаём и вставляем новый узел
  106.    if (cmp)
  107.    {
  108.       node = (TNode*) malloc(sizeof(TNode));
  109.       node->pstr = pstr;
  110.       node->length = length;
  111.       node->count = 1;
  112.       node->next = cur->next;
  113.       cur->next = node;
  114.  
  115.       // В случае если слово попало на вершину списка
  116.       if (cur == head)
  117.       {
  118.          *list = node;
  119.       }
  120.    }
  121.    // Слово уже есть
  122.    else
  123.    {
  124.       cur->next->count++;
  125.    }
  126.  
  127.    free(head);
  128.  
  129.    return *list;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Очищаем всеь список
  133. void Clear(TNode** list)
  134. {
  135.    TNode* node;
  136.  
  137.    // Перебираем все эелементы и удаляем каждый узел
  138.    while (*list)
  139.    {
  140.       node = *list;
  141.       *list = node->next;
  142.       free(node);
  143.    }
  144. }
  145. //-----------------------------------------------------------------------------
  146. // Печать списка
  147. void Print(const TNode* list, FILE* stream)
  148. {
  149.    for (; list; list = list->next)
  150.    {
  151.       fprintf(stream, "\t%4d : %.*s\n", list->count, list->length, list->pstr);
  152.    }
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Вормируем из текста 2 списка. В одном храняться информация о словах
  156. // начинающихся на гласные буквы, в другом - на согласные. Оба списка не
  157. // дублируют слова из text, а хранять лишь указатели.
  158. void GetLists(char* text, TNode** a, TNode** b)
  159. {
  160.    const char CChars[] = "аеёиоуыэюя";
  161.    char* begin;
  162.    char* end;
  163.  
  164.    while (GetWord(text, &begin, &end) > 0)
  165.    {
  166.       if (strchr(CChars, ToLower(*begin)))
  167.       {
  168.          PushWithSortAndCount(a, begin, end - begin);
  169.       }
  170.       else
  171.       {
  172.          PushWithSortAndCount(b, begin, end - begin);
  173.       }
  174.       text = end;
  175.    }
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Загружаем содержимое файла в память
  179. char* GetTextFromFile(const char* fname)
  180. {
  181.    FILE* f = fopen(fname, "rb");
  182.  
  183.    if (f == NULL)
  184.    {
  185.       perror(fname);
  186.       system("pause");
  187.       exit (EXIT_FAILURE);
  188.    }
  189.  
  190.    // Определяем размер файла
  191.    fseek(f, 0, SEEK_END);
  192.    size_t size = ftell(f);
  193.    fseek(f, 0, SEEK_SET);
  194.  
  195.  
  196.    char* text = (char*) malloc(size + 1);
  197.    text[size] = '\0';
  198.  
  199.    // Загружаем
  200.    fread(text, size, 1, f);
  201.  
  202.    fclose(f);
  203.  
  204.    return text;
  205. }
  206. //-----------------------------------------------------------------------------
  207.  
  208. int main(int argc, char* argv[])
  209. {
  210.    if (argc != 2)
  211.    {
  212.       fprintf(stdout, "Использование: program <ТЕКСТОВЫЙ ФАЙЛ>\n"
  213.                       "Примечание: текстовый фал должен быть в кодировке CP866\n");
  214.       system("pause");
  215.       return EXIT_FAILURE;
  216.    }
  217.  
  218.    char* text = GetTextFromFile(argv[1]);
  219.    TNode* a = NULL;
  220.    TNode* b = NULL;
  221.  
  222.    GetLists(text, &a, &b);
  223.  
  224.    fprintf(stdout, "Сам текст\n"
  225.                    "-----------------------\n"
  226.                    "%s\n\n", text);
  227.  
  228.    fprintf(stdout, "Начинающиеся на гласные\n"
  229.                    "-----------------------\n");
  230.    Print(a, stdout);
  231.  
  232.    fprintf(stdout, "Начинающиеся на согласные\n"
  233.                    "-----------------------\n");
  234.    Print(b, stdout);
  235.  
  236.    Clear(&a);
  237.    Clear(&b);
  238.  
  239.    free(text);
  240.  
  241.    system("pause");
  242.  
  243.    return EXIT_SUCCESS;
  244. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.182 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы