МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра Вычислительной техники
КУРСОВАЯ РАБОТА по дисциплине «Программирование»
ТЕМА: «Обработка текстовой информации»
Студент гр. - |
- |
|
Преподаватель |
|
Хахаев И. А. |
Санкт-Петербург
2022
Оглавление |
|
Введение.............................................................................................................................................. |
3 |
Постановка задачи и описание решения.......................................................................................... |
3 |
Структура вызовов функций............................................................................................................. |
4 |
Описание функций............................................................................................................................. |
4 |
Описание переменных........................................................................................................................ |
5 |
Cхемы алгоритмов.............................................................................................................................. |
7 |
Контрольные примеры..................................................................................................................... |
16 |
Текст программы.............................................................................................................................. |
18 |
Примеры работы программы........................................................................................................... |
23 |
Заключение........................................................................................................................................ |
25 |
2
Введение
Цель работы: законченное поэтапное решение содержательной задачи (постановка задачи, спецификация, выбор структур данных и разработка алгоритма, программная реализация, тестирование).
Задание (вариант 99): разработать алгоритм и написать программу, заменяющую в тексте программ на Си комментарии в стиле С++ ( // comment text ) на комментарии в стиле Си ( /* comment text */ ) с сохранением текста комментария.
Постановка задачи и описание решения
Прежде всего нужно уяснить, что комментарий не может быть частью строки (внутри кавычек) и не может быть частью другого комментария. Иначе говоря, если на вход подаётся текст с кодом Си и комментариями С++, на выходе должен остаться полностью компилируемый код Си с неизменным содержанием комментариев. Так же в C++ зачастую могут встречаться многострочные комментарии Си, поэтому алгоритм должен уметь их определять и игнорировать их содержимое, даже если внутри такого комментария есть начало комментария С++. Поскольку пустые комментарии — всё-таки тоже комментарии, они тоже должны быть обработаны алгоритмом.
Для оптимизации работы с памятью максимальный размер строк и текста в программе будет задаваться идентификатором MAXLEN, а связанные с этим ограничения будут выводиться программой при старте. Весь код главной функции находится в цикле, что позволяет без перезапуска тестировать разные варианты входных данных, а так же отследить возможные утечки памяти, которые обязательно дадут о себе знать на большом количестве тестов.
После начального диалога с пользователем программа создаёт массив размером MAXLEN * MAXLEN и записывает туда текст с помощью функции, соответствующей выбранному типу ввода. Функции ввода устроены таким образом, чтобы гарантировать, что текст будет заканчиваться нулём. Затем размер массива сокращается до минимально возможного с помощью realloc и отправляется сначала на подчёркивание комментариев (этот этап существует только для демонстрации алгоритма определения комментария), а потом и на вывод в файл или консоль с сопутствующей заменой всех комментариев.
3
Структура вызовов функций
read_from_console read_from_file
main
print_analysis write_result
print_line_of_chars
Описание функций
size_t read_from_console(char *buffer, size_t size, char *last_str)
Считывает строки с консоли в промежуточный массив размером MAXLEN, пока отдельно не будет введена строка last_str, и затем записывает в массив buffer, проверяя переполнение с помощью размера size. В обязательном порядке ставит нуль-терминатор в конец полученного текста. Возвращает размер данных, записанных в buffer.
size_t read_from_file(char *buffer, size_t size, FILE *file)
Считывает данные из файла file в массив buffer размера size, пока не наткнётся на нулевой байт или конец файла. В обязательном порядке ставит нуль-терминатор в конец полученного текста. Возвращает размер данных, записанных в buffer.
void print_line_of_chars(size_t n, char c)
Вспомогательная функция для вывода в консоль линий длиной n из символов с при подчёркивании комментариев.
void write_result(char *buffer, FILE *file)
Функция замены комментариев устроена достаточно просто — используется посимвольный проход по всему тексту с непосредственной записью символов в цикле. Можно было бы искать первое вхождение “//” в каждой строке и так определять начало комментария, однако в случае проверки дополнительных условий такой подход не состоятелен.
На вход принимает массив buffer – текст с нулём в конце и file – дескриптор потокого вывода, будь то файл или консоль.
void print_analysis(char *buffer)
Эта функция устроена практически так же, как и write_result, но в отличие от неё выводит содержимое buffer в консоль в неизменном виде, подчёркивая комментарии для замены.
4
Описание переменных int main()
№ |
Имя переменной |
Тип |
|
Назначение |
|
|
|
|
|
|
|
1 |
size |
size_t |
Размер массива text |
|
|
|
|
|
|
||
|
|
|
Указатель на динамический массив, в |
||
2 |
text |
char * |
который записывается |
текст для |
|
|
|
|
обработки |
|
|
|
|
|
|
|
|
|
|
|
Статический |
массив |
размером |
3 |
input_str |
char [] |
MAXLEN, в котором хранится или путь |
||
|
|
|
до файла на вход или строка console |
||
|
|
|
|
|
|
|
|
|
Статический |
массив |
размером |
4 |
output_str |
char [] |
MAXLEN, в котором хранится или путь |
||
|
|
|
до файла на выход или строка console |
||
|
|
|
|
||
5 |
input |
FILE * |
Дескриптор потокового входа |
||
|
|
|
|
||
6 |
output |
FILE * |
Дескриптор потокового выхода |
||
|
|
|
|
|
|
size_t read_from_console(char *buffer, size_t size, char *last_str)
№ |
Имя переменной |
Тип |
|
Назначение |
|
|
|
|
|
||
1 |
buffer |
char * |
Массив для записи данных с консоли |
||
|
|
|
|
||
2 |
size |
size_t |
Размер массива buffer |
||
|
|
|
|
|
|
3 |
last_str |
char |
* |
Строка, которая означает конец ввода |
|
|
|
|
|
|
|
4 |
с |
char |
* |
Указатель на рассматриваемый символ в |
|
строке temp |
|||||
|
|
|
|
||
|
|
|
|
|
|
5 |
temp |
char [] |
Массив, в который записывается строка |
||
с консоли |
|||||
|
|
|
|
||
|
|
|
|
|
|
6 |
res_size |
size_t |
Размер данных, записанных в массив |
||
buffer |
|||||
|
|
|
|
||
|
|
|
|
|
size_t read_from_file(char *buffer, size_t size, FILE *file)
№ |
Имя переменной |
Тип |
Назначение |
|
|
|
|
1 |
buffer |
char * |
Массив для записи данных с файла |
|
|
|
|
2 |
size |
size_t |
Размер массива buffer |
|
|
|
|
3 |
file |
FILE * |
Дескриптор файла, открытого на чтение |
|
|
|
|
5
4 |
res_size |
size_t |
Размер данных, записанных в массив |
|
buffer |
||||
|
|
|
||
|
|
|
|
void print_line_of_chars(size_t n, char c)
№ |
Имя переменной |
Тип |
Назначение |
|
|
|
|
|
|
1 |
n |
size_t |
Размер строки для вывода |
|
|
|
|
|
|
2 |
c |
char |
Символ, из которого будет состоять |
|
выходная строка |
||||
|
|
|
||
|
|
|
|
|
3 |
i |
size_t |
Счётчик |
|
|
|
|
|
6
void write_result(char *buffer, FILE *file) |
|
|
|
|
|||||
|
|
|
|
|
|
|
|||
№ |
Имя переменной |
Тип |
|
|
|
Назначение |
|||
1 |
buffer |
char |
* |
Массив |
символов |
для обработки, |
|||
оканчивающийся нулём |
|||||||||
|
|
|
|
||||||
2 |
file |
FILE * |
Дескриптор потока, открытого на запись |
||||||
3 |
last_c |
char |
|
Символ из предыдущей итерации цикла |
|||||
4 |
is_cpp_style |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит комментарию С++ |
||||||||
|
|
|
|
||||||
5 |
is_c_style |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит комментарию С |
||||||||
|
|
|
|
||||||
6 |
is_string |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит строке |
||||||||
|
|
|
|
||||||
7 |
need_to_print |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ нужно записывать в file |
||||||||
|
|
|
|
||||||
8 |
c |
char |
* |
Указатель на рассматриваемый символ в |
|||||
массиве buffer |
|
|
|||||||
|
|
|
|
|
|
7
void print_analysis(char *buffer) |
|
|
|
|
|
|
|||
№ |
Имя переменной |
Тип |
|
|
|
Назначение |
|||
1 |
buffer |
char |
* |
Массив |
символов |
для обработки, |
|||
оканчивающийся нулём |
|||||||||
|
|
|
|
||||||
|
|
|
|
|
|||||
2 |
last_c |
char |
|
Символ из предыдущей итерации цикла |
|||||
3 |
is_cpp_style |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит комментарию С++ |
||||||||
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
4 |
is_c_style |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит комментарию С |
||||||||
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
5 |
is_string |
char |
|
Флаг |
о |
том, |
что |
рассматриваемый |
|
|
символ принадлежит строке |
||||||||
|
|
|
|
||||||
|
|
|
|
|
|||||
6 |
c |
char |
* |
Указатель на рассматриваемый символ в |
|||||
массиве buffer |
|
|
|||||||
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
||
7 |
line_start |
char |
* |
Указатель |
на |
начало |
рассматриваемой |
||
строки в массиве buffer |
|||||||||
|
|
|
|
||||||
|
|
|
|
|
|||||
8 |
comment_start |
char |
* |
Указатель на начало рассматриваемого |
|||||
комментария в массиве buffer |
|||||||||
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
8