Constructor de strings dinámico
Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 59 de 61.
Desafío
FácilVamos 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 estructuraStringBuildercon tres miembros: unchar*buffer, unsize_tpara la longitud actual y unsize_tpara 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 usareallocpara aumentar el buffer. Luego concatena el nuevo texto usandostrcat.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 usandofgetsy añádela a tu StringBuilder. Después de añadir todas las cadenas, imprime la cadena completa ensamblada usandoget_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 enappendcuando 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ídosize - 1caracteres. Mantiene el carácter de nueva línea en el buffer, por lo que deberás eliminarlo manualmente. Úsalo enmain.cpara 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á:
- El número de cadenas a añadir
- Cada cadena en una línea separada
Ejemplo de salida cuando las entradas son 3, luego Hello, , World:
Hello WorldEjemplo 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:
SingleStringRecuerda 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
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculo