Arrays char en C: guía básica de manipulación de cadenas

目次

1. Introducción

El lenguaje C sigue siendo ampliamente utilizado en el desarrollo de sistemas y en entornos de desarrollo embebido. Dentro de ello, los arrays de char son uno de los elementos sintácticos más básicos e importantes para manejar cadenas de texto.

El lenguaje C no tiene un tipo de cadena estándar. En su lugar, se representa una cadena usando un array de caracteres (array de char). Esto no es muy intuitivo para los principiantes, por lo que comprender los arrays de char a menudo se convierte en una gran barrera al aprender C.

Además, si no se comprende la diferencia entre arrays de char y punteros a char (char*), así como la existencia del carácter nulo (\0) y otros detalles, pueden surgir errores inesperados.

En este artículo nos enfocamos en el tema \»C language char array\», y explicamos de manera clara desde el uso básico hasta técnicas avanzadas y cómo evitar errores comunes.

Si estás a punto de aprender C de forma seria o deseas repasar los arrays de char, te invitamos a leer hasta el final. En el siguiente capítulo explicaremos primero la definición y el funcionamiento básico de los arrays de char.

2. ¿Qué es una matriz de char?

En el lenguaje C, una «matriz de char» es una matriz para almacenar varios caracteres (tipo char). Esta es la estructura básica para manejar cadenas de texto.

¿Qué es el tipo char?

En C, char es un tipo de datos para representar un solo carácter. Por ejemplo, se puede definir una variable de un carácter de la siguiente manera.

char c = 'A';

De esta manera, 'A' como un carácter rodeado por comillas simples se define como tipo char.

Sintaxis básica de una matriz de char

Para almacenar varios caracteres, se usa una matriz del tipo char. Se define de la siguiente manera:

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

Esta matriz reserva un área de memoria de 6 caracteres, que corresponde a la cadena de 5 caracteres "Hello" más el carácter nulo (\0).

Importancia del carácter nulo ('

Tamaño de la matriz y consideraciones

'
)

En C, se usa el carácter nulo '\0' para indicar el final de una cadena. Si este símbolo no está presente, las funciones de manipulación de cadenas pueden no funcionar correctamente y pueden producir comportamientos inesperados.

char str[] = "Hello"; // Se agrega automáticamente '\0' al final

Como se muestra arriba, si se usa un literal de cadena entre comillas dobles, el compilador agrega automáticamente '\0' al final.

年収訴求

3. Declaración e inicialización de arreglos char

Al usar matrices de char, es fundamental reservar un tamaño de número de caracteres necesarios + 1 (para el carácter nulo). Si se asigna una cadena a una matriz con tamaño insuficiente, puede provocar un desbordamiento de buffer y el programa podría terminar inesperadamente.

Declaración e inicialización estática

Para usar arreglos char, primero se necesita declaración e inicialización adecuadas. Aquí se explica desde los métodos básicos de declaración de arreglos char en C, cómo inicializarlos y también el uso de memoria dinámica.

Inicialización mediante literal de cadena

Como método más básico, se puede declarar especificando el tamaño del arreglo y inicializarlo carácter por carácter.

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

Al hacerlo, str se puede tratar como la cadena "Hello". Es importante incluir siempre '\0' al final.

Asignación de literal con tamaño especificado

En C, también es posible una inicialización sencilla usando literales de cadena como se muestra a continuación.

char str[] = "Hello";

En este caso, el tamaño del arreglo se determina automáticamente como "Hello" + '\0', es decir, 6 caracteres. Si se desea modificar el contenido de la cadena, declararlo como un arreglo char permite cambiarlo de forma segura.

Uso de asignación de memoria dinámica (malloc)

También es posible inicializar con un literal de cadena especificando el tamaño del arreglo, pero hay que tener cuidado con insuficiencia de tamaño.

char str[5] = "Hello"; // ❌ Causa del error (tamaño insuficiente)

Como se muestra arriba, "Hello" requiere 5 caracteres más 1 carácter (‘\0’), un total de 6 caracteres. Por lo tanto, al menos debe ser char str[6].

4. Operación de cadenas

Si se desea manejar cadenas de forma más flexible, existe el método de usar malloc para asignar dinámicamente un arreglo char.

#include 
#include 

char* str = malloc(6 * sizeof(char));
strcpy(str, "Hello");

Con este método, la memoria se asigna dinámicamente y se maneja la cadena a través del puntero. Después de usarla, no debe olvidarse de liberar la memoria con free(str);.

Copia de cadena: strcpy

En C, es habitual utilizar las funciones de la biblioteca estándar para la manipulación de cadenas mediante arrays de char. Aquí se explican las funciones básicas de manipulación de cadenas y su uso, con ejemplos concretos.

Concatenación de cadenas: strcat

strcpy es una función que copia una cadena a otro array de char.

#include 

char src[] = "Hello";
char dest[10];
strcpy(dest, src);

Punto de atención: dest no tiene un tamaño suficiente, lo que puede provocar un desbordamiento de búfer. Asegúrese de reservar el tamaño de la longitud de la cadena a copiar más 1 (carácter nulo).

Obtención de la longitud de una cadena: strlen

strcat concatena dos cadenas. Añade el contenido del segundo argumento al final del primer argumento.

#include 

char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);

Como resultado, str1 será "Hello World". Además, se asume que el array del primer argumento tiene espacio suficiente para el tamaño total después de la concatenación.

Comparación de cadenas: strcmp

strlen devuelve la longitud de la cadena (número de caracteres sin contar el carácter nulo).

#include 

char str[] = "Hello";
int len = strlen(str); // len = 5

El carácter nulo no se cuenta, por lo que los que no están familiarizados con C deben tener cuidado.

Búsqueda en cadenas: strchr y strstr

Para comparar si dos cadenas son iguales, se utiliza strcmp.

#include 

char str1[] = "Hello";
char str2[] = "World";

if (strcmp(str1, str2) == 0) {
    // iguales
} else {
    // diferentes
}

Esta función devuelve 0 si son iguales y, si son diferentes, devuelve la diferencia de los códigos de los caracteres.

5. Diferencia entre arreglos char y punteros

Para buscar un carácter o una subcadena específica, se pueden usar las siguientes funciones.

#include 

char str[] = "Hello World";

// Búsqueda de carácter
char *ptr1 = strchr(str, 'o'); // Puntero al primer 'o'

// Búsqueda de subcadena
char *ptr2 = strstr(str, "World"); // Puntero a la posición inicial de "World"

Si no se encuentra, ambas funciones devuelven NULL.

Declaración

Al trabajar con cadenas en C, los arreglos char y los punteros char (char*) parecen similares, pero en realidad poseen propiedades diferentes. Comprender correctamente esta diferencia ayuda a evitar un uso incorrecto de la memoria y errores inesperados.

Diferencia en la capacidad de modificación

Primero veamos la diferencia en la forma de declarar.

char str1[] = "Hello";  // arreglo char
char *str2 = "Hello";   // puntero char

str1 es un arreglo con entidad y se reservan 6 bytes en memoria («Hello» + ‘\\0’). Por otro lado, str2 es un puntero a la zona de memoria donde se almacena el literal de cadena.

Diferencia en la estructura de memoria

El str1, que es un arreglo char, permite modificar libremente los caracteres dentro del arreglo.

str1[0] = 'h'; // OK

Sin embargo, cuando se accede con un puntero a un literal de cadena, como char* str2 = "Hello";, modificar su contenido es un comportamiento indefinido.

str2[0] = 'h'; // ❌ comportamiento indefinido (posible error en tiempo de ejecución)

Diferencia al obtener el tamaño

  • array de char
  • puntero charárea de constantes (solo lectura)área de heap (malloc, etc.)es necesario prestar atención al manejo de la memoria

Resumen: puntos clave para su uso

En el caso de un arreglo, sizeof(str1) devuelve el número total de bytes del arreglo.

char str1[] = "Hello";
printf("%lu", sizeof(str1)); // → 6 (incluye '\\0')

Por otro lado, en un puntero, sizeof(str2) devuelve el tamaño del propio puntero (normalmente 4‑8 bytes), por lo que no puede usarse con el objetivo de obtener el tamaño del arreglo.

char *str2 = "Hello";
printf("%lu", sizeof(str2)); // → 8 (entorno de 64 bits)

 

6. Paso de arreglos char a funciones

Elementoarray de charpuntero char
Cambio de contenidoposibleEn principio, no permitido (en caso de literal)
Obtener tamañoSe puede obtener con precisión con sizeof()strlen()
Uso de reescrituraEs adecuadoNo apto(solo lectura)
flexibilidadtamaño fijoEs flexible, pero se necesita precaución.

Ejemplo básico: paso de arreglo char como argumento

En C, al pasar un arreglo a una función se utiliza paso por puntero en lugar de paso por valor. Esto también se aplica a arreglo char, y al pasar a una función se pasa la dirección inicial (puntero) del arreglo.

Comprender este mecanismo es muy importante en situaciones donde se manipulan o modifican cadenas entre funciones.

Función que modifica el contenido

#include 

void printString(char str[]) {
    printf("Cadena: %s
", str);
}

int main() {
    char greeting[] = "Hello";
    printString(greeting);
    return 0;
}

En este ejemplo, se pasa a la función printString un argumento del tipo char[], pero en realidad se recibe como char*@@. Es decir, char str[] tiene el mismo significado que char *str.

Gestión del tamaño del arreglo

Incluso cuando se modifica el contenido del arreglo dentro de la función, se puede operar directamente los datos a través de la dirección pasada.

#include 

void toUpperCase(char str[]) {
    for (int i = 0; str[i] != ' '; i++) {
        if ('a' <= str[i] && str[i] <= 'z') {
            str[i] = str[i] - ('a' - 'A');
        }
    }
}

int main() {
    char text[] = "hello world";
    toUpperCase(text);
    printf("%s
", text); // Salida: HELLO WORLD
    return 0;
}

De esta manera, incluso si se desea cambiar el contenido del arreglo, al ser tratado como puntero, la operación dentro de la función se refleja en el llamador.

Argumentos de solo lectura usando const

En C, al pasar un arreglo a una función no se transmite la información de tamaño. Por lo tanto, la mejor práctica es pasar también el tamaño como argumento para operar de forma segura.

void printChars(char str[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%c ", str[i]);
    }
    printf("
");
}

Además, es común usar la función strlen para obtener dinámicamente la longitud de una cadena. Sin embargo, tenga cuidado de no usarla con arreglos que no estén terminados en nulo.

7. Ejemplo práctico: Mostrar cadena en orden inverso

Si la cadena no se va a modificar dentro de la función, es recomendable usar const char* para indicar que es de solo lectura.

void printConstString(const char *str) {
    printf("%s
", str);
}

Esto ayuda a prevenir modificaciones no intencionadas y a comunicar claramente la especificación de la función.

Objetivo

En esta sección, utilizaremos los conocimientos sobre arreglo de char que hemos aprendido hasta ahora para crear un programa para mostrar la cadena en orden inverso.

Código de ejemplo

Se imprimirá la cadena ingresada por el usuario, carácter por carácter, desde el final hasta el principio. Esto es muy útil como práctica de operaciones de arreglo, obtención de la longitud de la cadena y práctica de procesamiento de bucles.

Explicación

#include 
#include 

void printReversed(char str[]) {
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--) {
        putchar(str[i]);
    }
    putchar('n');
}

int main() {
    char text[100];

    printf("Ingrese la cadena:");
    fgets(text, sizeof(text), stdin);

    // Eliminar el carácter de nueva línea (medida para fgets)
    size_t len = strlen(text);
    if (len > 0 && text[len - 1] == 'n') {
        text[len - 1] = '\0';
    }

    printf("Al mostrar en orden inverso:");
    printReversed(text);

    return 0;
}

Ejemplo de ejecución

  • fgets
  • No olvides también procesar la eliminación de (carácter de salto de línea) que se agrega al final de la entrada.
  • strlen()

Consejos de aplicación

Ingrese la cadena: OpenAI
Al mostrar en orden inverso: IAnepO

8. Errores comunes y sus soluciones

Este proceso se puede aplicar a la verificación de palíndromos y a la comprensión de la estructura de pila, entre otras aplicaciones al aprender algoritmos. Además, es posible reescribirlo usando aritmética de punteros, lo que lo convierte en un material de práctica más avanzado.

1. Olvido de la terminación nula(

2. Insuficiencia del tamaño del búfer

Al trabajar con char配列 en C, existen varias trampas en las que pueden caer tanto principiantes como usuarios avanzados. Aquí explicaremos concretamente los errores frecuentes y sus medidas preventivas y soluciones.

3. Modificación de literales de cadena

Uno de los errores más comunes es olvidar añadir el carácter nulo(\0) al final de la cadena.

char str[5] = {'H', 'e', 'l', 'l', 'o'}; // ❌ Falta '\0' al final
printf("%sn", str); // Comportamiento indefinido

Solución:

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // ✅ Correcto

O, al usar un literal de cadena, el carácter nulo se agrega automáticamente.

4. Olvido de procesar el carácter de nueva línea de fgets

strcpy y strcat, si el tamaño del arreglo de destino es insuficiente, provocan corrupción de memoria (desbordamiento de búfer).

char str1[5];
strcpy(str1, "Hello"); // ❌ Copia 6 caracteres en un arreglo de tamaño 5

Solución:

@@@@char str1[6]; strncpy(str1, "Hello", sizeof(str1) - 1); str1[5] = '\0'; // Por precaución, se indica explícitamente el carácter nulo al final

5. Confusión entre punteros y arreglos

char *str = "Hello"; puede apuntar a una zona no modificable (posibilidad de que apunte a una zona no modificable). Escribir en él genera un error en tiempo de ejecución.

char *str = "Hello";
str[0] = 'h'; // ❌ Falla de segmentación en tiempo de ejecución

Solución:

char str[] = "Hello"; // ✅ Declarado como arreglo modificable
str[0] = 'h';

9. Resumen

Al usar fgets para obtener una cadena, es necesario tener en cuenta que queda un carácter de nueva línea (n) al final.

fgets(str, sizeof(str), stdin);
// str contendrá algo como "Hellon\0"

Solución:size_t len = strlen(str); if (len > 0 && str[len – 1] == ‘n’) { str[len – 1] = ‘\0’; }

Lo que se aprendió en este artículo

Debido a su apariencia similar, char* y char[] pueden confundirse, lo que puede conducir a un comportamiento indefinido. Es necesario ser consciente de la diferencia en la obtención del tamaño (sizeof) y de la diferencia en la capacidad de modificación.

Consejos para el aprendizaje futuro

En este artículo, hemos explicado paso a paso los “arrays de char en C” desde lo básico hasta lo avanzado. Finalmente, repasaremos el contenido del artículo y presentaremos una guía para el aprendizaje futuro.

Lo que se aprendió en este artículo

  • El papel y la forma de declarar los arreglos de char En el lenguaje C, no existe un tipo de dato de cadena, por lo que para manejar cadenas se utilizan arreglos de tipo char.
  • Importancia de los literales de cadena y el carácter nulo (\0) Para representar una cadena, es indispensable un carácter nulo al final.
  • Manipulación de cadenas con funciones de la biblioteca estándar , , , Si se usan, se pueden procesar cadenas de manera eficiente.
  • Diferencias entre char arrays y char pointers Los arrays y los punteros son similares pero no idénticos, y hay diferencias claras en la estructura de memoria y la posibilidad de reescritura.
  • Cómo pasar arreglos a funciones y consideraciones de seguridad Los arreglos se pasan en realidad como punteros, por lo que es necesario prestar atención a la reescritura y la gestión del tamaño.
  • Consolidación de la comprensión a través de ejemplos prácticos y errores comunes Aprendimos a usarlo de manera más realista mediante la aplicación en código real y la forma de manejar errores.

Consejos para el aprendizaje futuro

Comprender cómo usar los arrays de char es, en C, el primer paso para entender los fundamentos de la manipulación de memoria. El conocimiento adquirido aquí se puede aplicar en los siguientes pasos, como se muestra a continuación.

  • Operaciones con punteros
  • Gestión de memoria dinámicamallocfree
  • Combinación con estructuras

Además, al leer código escrito por otras personas, puedes absorber perspectivas y estilos que no tenías. Adoptar el hábito de leer proyectos reales y OSS (software de código abierto) también es muy útil.

C es muy flexible, lo que implica riesgos si no se maneja correctamente, pero si construyes la base con cuidado, se convierte en una herramienta muy poderosa. Entender los arrays de char es el primer paso. Por favor, usa este artículo como referencia y mejora tus habilidades de manera constante.