Menu
Coddy logo textTech

Constructor de strings dinámico

Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 59 de 61.

challenge icon

Desafío

Fácil

Vamos a construir un StringBuilder — un contenedor de cadenas dinámico que crece automáticamente a medida que se añade texto. Esta es una utilidad práctica que combina la gestión dinámica de memoria con los patrones de POO que has dominado a lo largo de este curso.

Organizarás tu código en tres archivos:

  • stringbuilder.h: Declara la estructura StringBuilder con tres miembros: un char* buffer, un size_t para la longitud actual y un size_t para la capacidad total. Declara los prototipos de función para crear un StringBuilder, añadirle texto, recuperar la cadena final y liberar la memoria. Los include guards son esenciales.
  • stringbuilder.c: Implementa tu sistema StringBuilder:
    • create_stringbuilder — asigna un StringBuilder en el heap, inicializa el buffer con una capacidad inicial de 16 bytes, establece la longitud en 0 y asegura que el buffer comience como una cadena vacía (terminada en nulo).
    • append — toma un puntero StringBuilder y una cadena para añadir. Calcula la nueva longitud requerida. Si excede la capacidad, duplica la capacidad (repetidamente si es necesario) y usa realloc para aumentar el buffer. Luego concatena el nuevo texto usando strcat.
    • get_string — devuelve un puntero al buffer interno (acceso de solo lectura).
    • free_stringbuilder — libera primero el buffer y luego la propia estructura StringBuilder.
  • main.c: Lee un entero que indica cuántas cadenas añadir. Luego lee cada cadena usando fgets y añádela a tu StringBuilder. Después de añadir todas las cadenas, imprime la cadena completa ensamblada usando get_string. Finalmente, libera el StringBuilder.

Dos funciones clave utilizadas en este desafío:

  • realloc(ptr, new_size) — redimensiona un bloque de memoria previamente asignado. Toma un puntero al bloque existente y el nuevo tamaño deseado en bytes, y devuelve un puntero al bloque redimensionado (posiblemente movido). Úsalo en append cuando el buffer necesite crecer:
    sb->buffer = (char*)realloc(sb->buffer, sb->capacity);
  • fgets(buffer, size, stream) — lee una línea de texto de un flujo de entrada en un array de caracteres, deteniéndose en una nueva línea o cuando se han leído size - 1 caracteres. Mantiene el carácter de nueva línea en el buffer, por lo que deberás eliminarlo manualmente. Úsalo en main.c para leer cada cadena de entrada:
    fgets(line, sizeof(line), stdin);
    Para eliminar la nueva línea final: comprueba si el último carácter es '\n' y reemplázalo con '\0'.

Tu programa recibirá:

  1. El número de cadenas a añadir
  2. Cada cadena en una línea separada

Ejemplo de salida cuando las entradas son 3, luego Hello, , World:

Hello World

Ejemplo de salida cuando las entradas son 4, luego C, is, a, great language!:

C is a great language!

Ejemplo de salida cuando las entradas son 1, luego SingleString:

SingleString

Recuerda actualizar el campo length después de cada operación de adición. Al comprobar si es necesaria la reasignación, ten en cuenta el terminador nulo — el buffer necesita espacio para length + new_text_length + 1 bytes. Usa strlen de <string.h> para medir las longitudes de las cadenas. También llama a getchar() después de scanf en main.c para consumir la nueva línea sobrante antes de leer las cadenas con fgets.

Pruébalo tú mismo

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

int main() {
    int n;
    scanf("%d", &n);
    getchar(); // consume el salto de línea después del número
    
    // TODO: Crea un StringBuilder usando create_stringbuilder()
    
    // TODO: Lee n cadenas y añade cada una al StringBuilder
    // Hint: Usa fgets o similar para leer cada línea
    // Recuerda manejar el carácter de salto de línea de fgets si lo usas
    
    // TODO: Imprime la cadena completa ensamblada usando get_string()
    
    // TODO: Libera el StringBuilder usando free_stringbuilder()
    
    return 0;
}

Todas las lecciones de Object Oriented Programming