String dinámica en C

En este post de programación en ANSI C o simplemente lenguaje C vamos a ver cómo tener una cadena dinámica que crece su tamaño sin ningún límite (más allá de la RAM).

Esto es, dicho de otra manera, una string dinámica a la que se le pueden concatenar más cadenas y va a crecer su tamaño según sea requerido.

Como bien sabes, las cadenas en C son arreglos de tipo char que tienen el carácter nulo en la última posición, y son de longitud fija.

Gracias a los apuntadores, estructuras y funciones como malloc o realloc podemos aumentar la memoria que una variable usa, logrando así tener una cadena dinámica en C a la que le puedes concatenar otros strings sin límite.

Estructura de la cadena dinámica en C

Necesitamos dos cosas para que esto funcione: el arreglo en sí, que será la cadena dinámica, y una variable para guardar la longitud de la cadena. Entonces definimos una estructura de la siguiente manera:

struct Cadena
{
    size_t longitud;
    char *datos;
};

Ahora inicializamos un struct estableciendo su longitud en cero pero sus datos como un arreglo de longitud 1 que solo tendrá el carácter nulo al final, quedando así:

void iniciarCadena(struct Cadena *cadena)
{
    cadena->longitud = 0;
    cadena->datos = malloc(1);
    cadena->datos[cadena->longitud] = '\0';
}

Aquí tenemos la primera llamada a malloc, y es que vamos a definir nuestra cadena dinámica usando simplemente un arreglo de caracteres al que accederemos usando aritmética de punteros.

Aumentar tamaño de cadena y concatenar

Una vez iniciada, veamos la función por la que seguramente estás aquí: función para concatenar una cadena en C aumentando su tamaño. Queda así:

void concatenar(struct Cadena *cadena, char *otraCadena)
{
    size_t longitudDeOtraCadena = strlen(otraCadena);
    size_t nuevaLongitud = cadena->longitud + longitudDeOtraCadena;
    size_t nuevaLongitudConByteNulo = nuevaLongitud + 1;
    size_t longitudDeOtraCadenaIncluyendoByteNulo = longitudDeOtraCadena + 1;
    char *cadenaConNuevaLongitud = realloc(cadena->datos, nuevaLongitudConByteNulo);
    if (cadenaConNuevaLongitud == NULL)
    {
        printf("Sin memoria suficiente para concatenar la nueva cadena");
        return;
    }
    cadena->datos = cadenaConNuevaLongitud;
    memcpy((char *)(cadena->datos + cadena->longitud), otraCadena, longitudDeOtraCadenaIncluyendoByteNulo);
    cadena->longitud = nuevaLongitud;
}

Aquí está todo lo interesante para aumentar el tamaño de la cadena y concatenar los nuevos datos. Como puedes ver estoy usando realloc para requerir más memoria a la cadena previamente alojada en la RAM, así como memcpy para concatenar los datos.

Modo de uso

Finalmente veamos cómo concatenar cadenas en C sin límite. Solo debes invocar a la función concatenar cuantas veces sea necesario, pasando el apuntador a la cadena y la cadena que quieres concatenar como segundo argumento.

int main()
{
    struct Cadena *miCadena = (struct Cadena *)malloc(sizeof(struct Cadena));
    if (miCadena == NULL)
    {
        printf("Sin memoria suficiente para alojar el struct de cadena");
        return EXIT_FAILURE;
    }
    iniciarCadena(miCadena);
    printf("La cadena inicial es: '%s'\n", miCadena->datos);
    concatenar(miCadena, "Hola mundo ");
    concatenar(miCadena, "parzibyte.me ");
    printf("La cadena es: '%s'\n", miCadena->datos);
    free(miCadena->datos);
    free(miCadena);
    return 0;
}

No te olvides de liberar la memoria con free al finalizar tu programa.

Compilación

Por cierto, vas a necesitar las librerías stdio.h, string.h y stdlib.h. En este caso usamos string.h solo para calcular la longitud de una cadena, pero siempre puedes usar otras alternativas.

Yo lo he compilado con MSYS2 usando gcc concatenar.c -Wall -o concatenar.exe y luego ejecutando concatenar.exe. Si te sirve, aquí hay un vídeo explicando todo lo del post:

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *