Написать прогу удаления комментариев - C (СИ)

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

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

Здравствуйте! Задача: Написать программму, которая бы удалила закомментированные строки (//, /* */) из исходного кода. При этом если комментарий был многострочный, то после удаления многострочного комментария убирала лишние пробельные символы. Функции main в качестве параметра указывать файл, в котором находится имена файлов, в которых нужно удалить комментарии.

Решение задачи: «Написать прогу удаления комментариев»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
typedef struct block_t
{
   char* begin;
   char* end;
   struct block_t* next;
}  TBlock;
 
typedef struct listblocks_t
{
   TBlock* head;
   TBlock* tail;
}  TListBlocks;
 
//-----------------------------------------------------------------------------
TListBlocks* Push(TListBlocks* list, char* begin, char* end)
{
   TBlock* node = (TBlock*) malloc(sizeof(TBlock));
   node->begin = begin;
   node->end = end;
   node->next = NULL;
 
   if (list->head && list->tail)
   {
      list->tail->next = node;
      list->tail = node;
   }
   else
   {
      list->head = list->tail = node;
   }
 
   return list;
}
//-----------------------------------------------------------------------------
void Clear(TListBlocks* list)
{
   TBlock* node;
 
   while (list->head)
   {
      node = list->head;
      list->head = list->head->next;
      free(node);
   }
 
   list->tail = NULL;
}
//-----------------------------------------------------------------------------
size_t GetFileSize(FILE* f)
{
   size_t pos = ftell(f);
 
   fseek(f, 0, SEEK_END);
 
   size_t size = ftell(f);
 
   fseek(f, pos, SEEK_SET);
 
   return size;
}
//-----------------------------------------------------------------------------
char* GetTextFromFile(const char* fname)
{
   FILE* f = fopen(fname, "r");
 
   size_t size = GetFileSize(f);
   char* text = (char*) malloc(size + 1);
   text[size] = 0;
 
   if (fread(text, size, 1, f) != 1)
   {
      free(text);
      text = NULL;
   }
 
   fclose(f);
 
   return text;
}
//-----------------------------------------------------------------------------
TListBlocks GetListFromText(char* text)
{
   const struct
   {
      struct
      {
         char* str;
         size_t len;
      }  begin, end;
   }  CDelim[] = { {{"/*", 2}, {"*/", 2}},
                   {{"//", 2}, {"\n", 1}} };
 
   size_t CDelimSize = sizeof(CDelim) / sizeof(*CDelim);
 
   TListBlocks list = { NULL, NULL };
 
   char* marker = text;
 
   int block = 0;
   size_t i;
 
   for (; *text; ++text)
   {
      if (block)
      {
         i = block - 1;
         if (strncmp(text, CDelim[i].end.str, CDelim[i].end.len) == 0)
         {
            text += CDelim[i].end.len - 1;
            marker = text + 1;
            block = 0;
         }
      }
      else
      {
         for (i = 0; (i < CDelimSize) && (block == 0); ++i)
         {
            if (strncmp(text, CDelim[i].begin.str, CDelim[i].begin.len) == 0)
            {
               if (text - marker > 1)
               {
 
                  Push(&list, marker, text);
               }
               text += CDelim[i].begin.len - 1;
               block = i + 1;
            }
         }
      }
   }
 
   if (text - marker > 1)
   {
      Push(&list, marker, text);
   }
 
   return list;
}
//-----------------------------------------------------------------------------
void PrintList(FILE* stream, const TListBlocks* list)
{
   const TBlock* node = list->head;
 
   for (; node; node = node->next)
   {
      fprintf(stream, "%.*s", node->end - node->begin, node->begin);
   }
}
//-----------------------------------------------------------------------------
void PrintToFile(const char* fname, const TListBlocks* list)
{
   FILE* f = fopen(fname, "w");
 
   PrintList(f, list);
 
   fclose(f);
}
//-----------------------------------------------------------------------------
void CheckFileExist(const char* fname)
{
   if (access(fname, 0) == -1)
   {
      fprintf(stderr, "error: file '%s' not found ...\n", fname);
      exit(EXIT_FAILURE);
   }
}
//-----------------------------------------------------------------------------
void CheckArgc(int argc)
{
   if (argc != 2)
   {
      fprintf(stderr, "Useage: program <FILE.c>\n");
      exit(EXIT_FAILURE);
   }
}
//-----------------------------------------------------------------------------
 
int main(int argc, const char* argv[])
{
   CheckArgc(argc);
   CheckFileExist(argv[1]);
 
   char* text = GetTextFromFile(argv[1]);
 
   TListBlocks list = GetListFromText(text);
 
   PrintList(stdout, &list);
 
   PrintToFile(argv[1], &list);
 
   Clear(&list);
 
   free(text);
 
   return EXIT_SUCCESS;
}

Объяснение кода листинга программы

  1. В начале кода подключаются необходимые заголовочные файлы:
    • stdio.h для работы с функциями ввода-вывода;
    • stdlib.h для работы с функциями стандартной библиотеки, такими как malloc и free;
    • string.h для работы со строками;
    • unistd.h для работы с функцией access.
  2. Далее определены типы данных и переменные:
    • TBlock - структура, представляющая собой блок текста;
    • TListBlocks - структура, представляющая собой список блоков текста;
    • CDelim - массив, содержащий различные варианты комментариев для удаления.
  3. Затем определены функции:
    • Push - добавляет новый блок в список;
    • Clear - очищает список;
    • GetFileSize - получает размер файла;
    • GetTextFromFile - читает текст из файла;
    • GetListFromText - извлекает список блоков из текста;
    • PrintList - выводит список на экран или в файл;
    • CheckFileExist - проверяет существование файла;
    • CheckArgc - проверяет корректность аргументов командной строки;
    • main - точка входа в программу.
  4. В функции main происходит следующее:
    • Проверка корректности аргументов командной строки;
    • Открытие файла и чтение его содержимого в строку;
    • Создание пустого списка;
    • Извлечение списка блоков из текста;
    • Вывод списка на экран;
    • Запись списка в файл;
    • Очистка списка и освобождение памяти.
  5. Программа завершается успешно, если все комментарии удалены и файл существует. В противном случае программа выводит сообщение об ошибке и завершается с кодом ошибки.

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


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

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

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