Написать прогу удаления комментариев - 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; }
Объяснение кода листинга программы
- В начале кода подключаются необходимые заголовочные файлы:
stdio.h
для работы с функциями ввода-вывода;stdlib.h
для работы с функциями стандартной библиотеки, такими какmalloc
иfree
;string.h
для работы со строками;unistd.h
для работы с функциейaccess
.
- Далее определены типы данных и переменные:
TBlock
- структура, представляющая собой блок текста;TListBlocks
- структура, представляющая собой список блоков текста;CDelim
- массив, содержащий различные варианты комментариев для удаления.
- Затем определены функции:
Push
- добавляет новый блок в список;Clear
- очищает список;GetFileSize
- получает размер файла;GetTextFromFile
- читает текст из файла;GetListFromText
- извлекает список блоков из текста;PrintList
- выводит список на экран или в файл;CheckFileExist
- проверяет существование файла;CheckArgc
- проверяет корректность аргументов командной строки;main
- точка входа в программу.
- В функции
main
происходит следующее:- Проверка корректности аргументов командной строки;
- Открытие файла и чтение его содержимого в строку;
- Создание пустого списка;
- Извлечение списка блоков из текста;
- Вывод списка на экран;
- Запись списка в файл;
- Очистка списка и освобождение памяти.
- Программа завершается успешно, если все комментарии удалены и файл существует. В противном случае программа выводит сообщение об ошибке и завершается с кодом ошибки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д