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

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

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

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

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

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct node_t
{
   char* pstr;          // Указатель на слово
   size_t length;       // Длина слова
   size_t count;        // Количество слов
   struct node_t* next; // Следующий узел
}  TNode;
 
//-----------------------------------------------------------------------------
// Функция меняет верхний регистр русских букв на ничжний
char ToLower(char c)
{
   if (('А' <= c) && (c <= 'П'))
   {
      c += 32;
   }
   else if (('Р' <= c) && (c <= 'Я'))
   {
      c += 80;
   }
   else if ('Ё' == c)
   {
      c = 'ё';
   }
 
   return c;
}
//-----------------------------------------------------------------------------
// Функция определяет является ли символ буквой русского алфавита
int IsAlpha(char c)
{
   return ((('А' <= c) && (c <= 'п') )||
           (('р' <= c) && (c <= 'ё')));
}
//-----------------------------------------------------------------------------
// Функция сравнивает 2 строки заданной длины.
// Ориентирована на русский алфавит. Сравнение регистронезависимое.
int StrNCmp(const char* a, size_t lenA, const char* b, size_t lenB)
{
   // Берём минимальную из длин
   size_t len = (lenA < lenB) ? lenA : lenB;
   int result = 0;
   int i;
 
   // Выполняем пока не достигнем минимальной длины
   // или пока не найдём различия
   for (i = 0; (i < len) && (result == 0); ++i)
   {
      result = ToLower(a[i]) - ToLower(b[i]);
   }
 
   // Если различий небыло, тогда пытаеся наёти
   // различия в длине
   if (result == 0)
   {
      result = lenA - lenB;
   }
 
   return result;
}
//-----------------------------------------------------------------------------
// Находит в заданной строке слово на русском языке.
// В begin передаётся указатель на начало слова, а end - конец
int GetWord(char* text, char** begin, char** end)
{
   // Перебирваем символы в строке пока не встретим
   // русскую букву (ну или пока текст не закончится)
   for (; *text && !IsAlpha(*text); ++text) { ; }
 
   *begin = text;
 
   // Перебирваем символы в строке пока встречаются
   // русские буквы
   for (; *text && IsAlpha(*text); ++text) { ; }
 
   *end = text;
 
   // Возвращаем длину найденного слова
   return *end - *begin;
}
//-----------------------------------------------------------------------------
// Функция добавляет в список новое слово не нарушая порядок сортировки списка.
// Если такое слово уже встречается, то значение count узла просто инкрементируется.
TNode* PushWithSortAndCount(TNode** list, char* pstr, size_t length)
{
   // Временно создаём самый верхний узел.
   // Создаётся для упрощения дальнейшего алгоритма
   TNode* head = (TNode*) malloc(sizeof(TNode));
   TNode* cur = head;
   TNode* node;
   int cmp = 1;
   head->next = *list;
 
   // Ищем мето, куда можно пристроить новое слово.
   // Если cmp будет равно 0, то это означает, что такое
   // слово уже есть
   for (; cur->next &&
          ((cmp = StrNCmp(cur->next->pstr, cur->next->length, pstr, length)) < 0)
        ; cur = cur->next) { ; }
 
   // Если слово не повторяется, то создаём и вставляем новый узел
   if (cmp)
   {
      node = (TNode*) malloc(sizeof(TNode));
      node->pstr = pstr;
      node->length = length;
      node->count = 1;
      node->next = cur->next;
      cur->next = node;
 
      // В случае если слово попало на вершину списка
      if (cur == head)
      {
         *list = node;
      }
   }
   // Слово уже есть
   else
   {
      cur->next->count++;
   }
 
   free(head);
 
   return *list;
}
//-----------------------------------------------------------------------------
// Очищаем всеь список
void Clear(TNode** list)
{
   TNode* node;
 
   // Перебираем все эелементы и удаляем каждый узел
   while (*list)
   {
      node = *list;
      *list = node->next;
      free(node);
   }
}
//-----------------------------------------------------------------------------
// Печать списка
void Print(const TNode* list, FILE* stream)
{
   for (; list; list = list->next)
   {
      fprintf(stream, "\t%4d : %.*s\n", list->count, list->length, list->pstr);
   }
}
//-----------------------------------------------------------------------------
// Вормируем из текста 2 списка. В одном храняться информация о словах
// начинающихся на гласные буквы, в другом - на согласные. Оба списка не
// дублируют слова из text, а хранять лишь указатели.
void GetLists(char* text, TNode** a, TNode** b)
{
   const char CChars[] = "аеёиоуыэюя";
   char* begin;
   char* end;
 
   while (GetWord(text, &begin, &end) > 0)
   {
      if (strchr(CChars, ToLower(*begin)))
      {
         PushWithSortAndCount(a, begin, end - begin);
      }
      else
      {
         PushWithSortAndCount(b, begin, end - begin);
      }
      text = end;
   }
}
//-----------------------------------------------------------------------------
// Загружаем содержимое файла в память
char* GetTextFromFile(const char* fname)
{
   FILE* f = fopen(fname, "rb");
 
   if (f == NULL)
   {
      perror(fname);
      system("pause");
      exit (EXIT_FAILURE);
   }
 
   // Определяем размер файла
   fseek(f, 0, SEEK_END);
   size_t size = ftell(f);
   fseek(f, 0, SEEK_SET);
 
 
   char* text = (char*) malloc(size + 1);
   text[size] = '\0';
 
   // Загружаем
   fread(text, size, 1, f);
 
   fclose(f);
 
   return text;
}
//-----------------------------------------------------------------------------
 
int main(int argc, char* argv[])
{
   if (argc != 2)
   {
      fprintf(stdout, "Использование: program <ТЕКСТОВЫЙ ФАЙЛ>\n"
                      "Примечание: текстовый фал должен быть в кодировке CP866\n");
      system("pause");
      return EXIT_FAILURE;
   }
 
   char* text = GetTextFromFile(argv[1]);
   TNode* a = NULL;
   TNode* b = NULL;
 
   GetLists(text, &a, &b);
 
   fprintf(stdout, "Сам текст\n"
                   "-----------------------\n"
                   "%s\n\n", text);
 
   fprintf(stdout, "Начинающиеся на гласные\n"
                   "-----------------------\n");
   Print(a, stdout);
 
   fprintf(stdout, "Начинающиеся на согласные\n"
                   "-----------------------\n");
   Print(b, stdout);
 
   Clear(&a);
   Clear(&b);
 
   free(text);
 
   system("pause");
 
   return EXIT_SUCCESS;
}

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


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

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

11   голосов , оценка 4.182 из 5
Похожие ответы