Динамический построитель строк
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 59 из 61.
Задание
ЛегкоДавайте создадим StringBuilder — динамический контейнер для строк, который автоматически увеличивается при добавлении текста. Это практическая утилита, сочетающая динамическое управление памятью с паттернами ООП, которые вы освоили в этом курсе.
Вы организуете свой код в трех файлах:
stringbuilder.h: Объявите структуруStringBuilderс тремя членами: буферомchar*,size_tдля текущей длины иsize_tдля общей емкости. Объявите прототипы функций для создания StringBuilder, добавления текста в него, получения итоговой строки и освобождения памяти. Использование include guards обязательно.stringbuilder.c: Реализуйте вашу систему StringBuilder:create_stringbuilder— выделяет StringBuilder в куче, инициализирует буфер с начальной емкостью 16 байт, устанавливает длину в 0 и гарантирует, что буфер начинается как пустая строка (с нулевым завершителем)append— принимает указатель на StringBuilder и строку для добавления. Рассчитайте новую необходимую длину. Если она превышает емкость, удвойте емкость (при необходимости несколько раз) и используйтеreallocдля увеличения буфера. Затем добавьте новый текст, используяstrcatget_string— возвращает указатель на внутренний буфер (доступ только для чтения)free_stringbuilder— сначала освобождает буфер, а затем саму структуру StringBuilder
main.c: Считайте целое число, указывающее, сколько строк нужно добавить. Затем считайте каждую строку с помощьюfgetsи добавьте ее в свой StringBuilder. После добавления всех строк выведите полную собранную строку с помощьюget_string. В конце освободите StringBuilder.
Две ключевые функции, используемые в этом испытании:
realloc(ptr, new_size)— изменяет размер ранее выделенного блока памяти. Она принимает указатель на существующий блок и новый желаемый размер в байтах и возвращает указатель на (возможно, перемещенный) блок измененного размера. Используйте ее вappend, когда буферу нужно вырасти:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream)— считывает строку текста из входного потока в символьный массив, останавливаясь на символе новой строки или когда считаноsize - 1символов. Она сохраняет символ новой строки в буфере, поэтому вам нужно будет удалить его вручную. Используйте ее вmain.cдля чтения каждой входной строки:fgets(line, sizeof(line), stdin);
Чтобы удалить завершающий символ новой строки: проверьте, является ли последний символ'\n', и замените его на'\0'.
Ваша программа получит:
- Количество строк для добавления
- Каждую строку на отдельной строке
Пример вывода, когда входные данные 3, затем Hello, , World:
Hello WorldПример вывода, когда входные данные 4, затем C, is, a, great language!:
C is a great language!Пример вывода, когда входные данные 1, затем SingleString:
SingleStringНе забудьте обновлять поле length после каждой операции добавления. При проверке необходимости перераспределения памяти учитывайте нулевой завершитель — буферу требуется место для length + new_text_length + 1 байт. Используйте strlen из <string.h> для измерения длины строк. Также вызовите getchar() после scanf в main.c, чтобы поглотить оставшийся символ новой строки перед чтением строк с помощью fgets.
Попробуйте сами
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // поглотить символ новой строки после числа
// TODO: Создайте StringBuilder с помощью create_stringbuilder()
// TODO: Прочитайте n строк и добавьте каждую в StringBuilder
// Подсказка: Используйте fgets или аналогичную функцию для чтения каждой строки
// Не забудьте обработать символ новой строки из fgets, если вы его используете
// TODO: Выведите готовую собранную строку с помощью get_string()
// TODO: Освободите память StringBuilder с помощью free_stringbuilder()
return 0;
}
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга