Menu
CoddyTech

Construtor Dinâmico de Strings

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 59 de 61.

challenge icon

Desafio

Fácil

Vamos criar um StringBuilder: um contêiner de strings dinâmico que cresce automaticamente à medida que você acrescenta texto. Esse é um utilitário prático que combina gerenciamento dinâmico de memória com os padrões de POO que você dominou ao longo deste curso.

Você organizará seu código em três arquivos:

  • stringbuilder.h: Declare a estrutura StringBuilder com três membros: um buffer char*, um size_t para o comprimento atual e um size_t para a capacidade total. Declare os protótipos das funções para criar um StringBuilder, acrescentar texto a ele, obter a string final e liberar a memória. As proteções contra inclusões repetidas são essenciais.
  • stringbuilder.c: Implemente seu sistema StringBuilder:
    • create_stringbuilder: aloca um StringBuilder no heap, inicializa o buffer com uma capacidade inicial de 16 bytes, define o comprimento como 0 e garante que o buffer comece como uma string vazia (terminada em nulo)
    • append: recebe um ponteiro para um StringBuilder e uma string para acrescentar. Calcule o novo comprimento necessário. Se ele exceder a capacidade, dobre a capacidade (repetidamente, se necessário) e use realloc para aumentar o buffer. Em seguida, concatene o novo texto usando strcat
    • get_string: retorna um ponteiro para o buffer interno (acesso somente para leitura)
    • free_stringbuilder: libera primeiro o buffer e, em seguida, a própria estrutura StringBuilder
  • main.c: Leia um número inteiro que indica quantas strings devem ser acrescentadas. Em seguida, leia cada string usando fgets e acrescente-a ao seu StringBuilder. Depois que todas as strings forem adicionadas, imprima a string completa montada usando get_string. Por fim, libere o StringBuilder.

Duas funções importantes usadas neste desafio:

  • realloc(ptr, new_size): redimensiona um bloco de memória previamente alocado. Recebe um ponteiro para o bloco existente e o novo tamanho desejado em bytes, e retorna um ponteiro para o bloco redimensionado (que pode ter sido movido). Use-a em append quando o buffer precisar crescer:
    sb->buffer = (char*)realloc(sb->buffer, sb->capacity);
  • fgets(buffer, size, stream): lê uma linha de texto de um fluxo de entrada para um array de caracteres, parando em uma quebra de linha ou quando size - 1 caracteres tiverem sido lidos. Ela mantém o caractere de quebra de linha no buffer, então você precisará removê-lo manualmente. Use-a em main.c para ler cada string de entrada:
    fgets(line, sizeof(line), stdin);
    Para remover a quebra de linha no final: verifique se o último caractere é '\n' e substitua-o por '\0'.

Seu programa receberá:

  1. O número de strings a acrescentar
  2. Cada string em uma linha separada

Exemplo de saída quando as entradas são 3, depois Hello, , World:

Hello World

Exemplo de saída quando as entradas são 4, depois C, is, a, great language!:

C is a great language!

Exemplo de saída quando a entrada é 1, depois SingleString:

SingleString

Lembre-se de atualizar o campo length após cada operação de acréscimo. Ao verificar se é necessário realocar, leve em conta o terminador nulo: o buffer precisa de espaço para length + new_text_length + 1 bytes. Use strlen de <string.h> para medir os comprimentos das strings. Também chame getchar() após scanf em main.c para consumir a quebra de linha restante antes de ler strings com fgets.

Experimente você mesmo

#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"

int main() {
    int n;
    scanf("%d", &n);
    getchar(); // consuma o caractere de nova linha após o número
    
    // TODO: Crie um StringBuilder usando create_stringbuilder()
    
    // TODO: Leia n strings e adicione cada uma ao StringBuilder
    // Dica: Use fgets ou algo semelhante para ler cada linha
    // Lembre-se de tratar o caractere de nova linha de fgets se usá-la
    
    // TODO: Imprima a string completa montada usando get_string()
    
    // TODO: Libere o StringBuilder usando free_stringbuilder()
    
    return 0;
}

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online