Si venías de programar en BASIC (Microsoft BASIC y algunos otros), o quizás Python, y has empezado a programar en C, te habrás encontrado con una paradoja: mientras en estos lenguajes de programación se manejan las cadenas de caracteres como un tipo de datos más, en C el manejo de cadenas de caracteres es diferente.
Conceptos Fundamentales de las Cadenas en C
C no dispone de un tipo de dato String para trabajar con cadenas de texto como en otros lenguajes. En su lugar, una cadena está representada por un arreglo de caracteres (char) habitualmente terminado con el carácter especial de fin de cadena « \0 ». Las C-Strings son arreglos de caracteres con un carácter nulo \0 al final que indica el final de una cadena. En este sentido, podemos definir una cadena de caracteres en C como un arreglo en el que cada elemento es de tipo char.
Los caracteres de una cadena se colocarán uno a continuación del otro en los elementos del arreglo, a partir del primero. Para saber dónde terminan los caracteres válidos en el arreglo, se debe colocar un valor de terminación al final de la secuencia de caracteres; este valor es cero, que representa al carácter cuyo código ASCII es cero. En el caso del array de caracteres “abc” con el carácter de fin de cadena decimos que consta de 4 elementos (contando el carácter especial de fin de cadena).
El tipo char, sin embargo, una variable definida de este tipo alberga números enteros entre -128 y 127 y no caracteres como lo hacen otros lenguajes como el Pascal. Es el compilador el que interpreta estos caracteres y los almacena en la memoria como representaciones binarias. Es por esta razón que una expresión puede darse de esta manera: a = 'A' + 32;, no es que se pretenda sumar el valor de 32 a la letra A, sino que se está sumando 32 al valor numérico que este carácter representa.
Secuencias de Escape
El carácter de escape \ en las cadenas nos sirve para establecer caracteres especiales que indican saltos de línea \n, tabulaciones \t, caracteres nulos \0, etc. Hay tres tipos de secuencias de escape: simple, octal, hexadecimal. Una secuencia de escape octal es una barra diagonal inversa seguida de una secuencia de uno a tres dígitos octales. Una secuencia de escape hexadecimal es una barra diagonal inversa seguida del carácter x y seguida de una secuencia de uno o varios dígitos hexadecimales.
Lea también: IVA 21% Excel
Declaración de Cadenas de Caracteres
Podemos declarar cadenas de varias maneras. Una forma común es especificar un arreglo de caracteres con un tamaño fijo, por ejemplo: char nombre[20];. Aquí, "nombre" es una cadena de caracteres que puede albergar hasta 19 caracteres, sin olvidar que se requiere un espacio para el delimitador de la cadena (cero o '\0').
En estos casos el array de caracteres tiene en C un carácter adicional además del texto visible, el correspondiente al final de cadena. Llamamos tamaño (length) de un array al número de elementos de que consta.
Inicialización de Cadenas
Como cualquier arreglo, una cadena de caracteres se puede inicializar en el momento de su declaración. Podemos hacerlo de varias formas:
- Con una lista de caracteres:
char nomb2[10] = {'H', 'o', 'l', 'a', '\0', '+', '\t', '{', '\n', 'A'};Si recordamos de los arreglos, si se colocan menos valores de inicialización que la capacidad del arreglo, el resto de elementos del arreglo se inicializa en cero.
- Con un literal de cadena:
char nomb4[10] = "Hola";
Esta es una forma concisa y común de inicializar cadenas, y el compilador automáticamente añade el carácter nulo '\0' al final si hay espacio suficiente.
Lea también: Guía IVA reducido
Lectura y Escritura de Cadenas de Caracteres
El lenguaje C implementa una serie de funciones que permiten el ingreso y la salida de cadenas de caracteres a, y desde, un programa.
Función scanf
La función scanf, empleando el especificador de formato %s, permite el ingreso de cadenas de caracteres. La función scanf irá tomando uno a uno los caracteres del búfer de entrada y los irá colocando consecutivamente en el arreglo a partir del primer elemento. Comentamos previamente que las funciones para pedir datos al usuario scanf y gets introducen automáticamente un fin de cadena (\0) al final del texto capturado.
La función scanf también se puede emplear con punteros, sin embargo se debe tener especial cuidado en el sentido de asegurar antes que el puntero apunte a una dirección válida.
Se denomina "conjunto de exploración" a una lista de caracteres que se coloca en la cadena de formato de la función scanf y permite restringir los caracteres que se pueden ingresar a una cadena de caracteres. También se puede negar un conjunto, de modo que se permita cualquier carácter menos los contenidos en el conjunto. Esto se logra poniendo el carácter ^ al inicio del conjunto.
Función printf
La función printf permite, empleando el especificador de formato %s, la impresión del contenido de un arreglo de tipo char, como caracteres en la consola. La función irá tomando cada uno de los elementos del arreglo e irá mostrando en la pantalla cada uno de los caracteres correspondientes, hasta encontrar el delimitador de la cadena (0 ó '\0').
Lea también: ¿Cómo localizar tus XML del SAT?
Funciones gets y puts
Otro par de funciones que permiten el ingreso y la salida de cadenas de caracteres son las funciones gets y puts. La función gets recibe como parámetro un arreglo de tipo char, en él se almacenarán los caracteres provenientes de la consola. A diferencia de printf, la lectura con gets no se detendrá cuando se encuentre un espacio en blanco sino hasta encontrar un carácter de cambio de línea. La función puts es equivalente a printf con la diferencia que cuando puts termina de imprimir los caracteres, envía a la pantalla un carácter de cambio de línea.
Manipulación de Cadenas
En el caso de las cadenas de caracteres, no se puede asignar valores como se hacen con las variables numéricas. La razón de esto es la forma como se definen las cadenas en C, mediante arreglos. Cuando en un programa se emplee el identificador del arreglo sin colocar un índice entre corchetes, se estará haciendo referencia a la dirección de memoria del inicio del área de datos del arreglo. Por otro lado, un valor constante dado para una cadena de caracteres se representa como una secuencia de caracteres encerrados entre comillas, por ejemplo: "Cadena", "Juan Perez Castro". Luego el compilador reemplaza el valor constante por la dirección de inicio del área asignada.
Para la asignación o la comparación de cadenas, habrá que elaborar una rutina que permita asignar o comparar carácter a carácter los elementos de un arreglo al otro. Por ejemplo, para comparar dos cadenas de caracteres, debemos elaborar una rutina que sea capaz de comparar carácter a carácter y así poder determinar si son iguales, si una es mayor que otra o viceversa.
Uso de la Librería string.h
Todos los compiladores de C implementan una biblioteca de funciones que permite, de una manera sencilla, la manipulación de cadenas de caracteres. Estas funciones trabajan con las cadenas de la misma manera que lo hemos explicado, es decir, manipulando carácter por carácter cada uno de los elementos del arreglo. A través de la librería string.h podemos usar distintas funciones relacionadas con cadenas. Para usar estas funciones debemos escribir #include
Funciones Comunes de la Librería string.h
Aquí se presenta una tabla con algunas de las funciones más importantes disponibles en la librería string.h para el manejo de cadenas en C:
| Función | Descripción |
|---|---|
| strlen(cad) | Devuelve el número de caracteres de la cadena "cad". No cuenta el carácter de terminación \0. |
| strcpy(destino, origen) | Copia todos los caracteres de la cadena origen en la cadena destino, incluso el carácter de terminación. Devuelve un puntero a destino. |
| strcat(destino, origen) | Agrega una copia de la cadena origen al final de la cadena destino. Devuelve la dirección a la que apunta la variable destino. |
| strcmp(cad1, cad2) | Compara uno a uno los caracteres de ambas cadenas hasta completarlos todos o hasta encontrar una diferencia. Devuelve cero (0) si ambas cadenas son iguales, un valor negativo si la primera cadena es menor que la segunda y un valor positivo si la primera es mayor que la segunda. |
| strstr(cad1, cad2) | Busca la primera ocurrencia de la cadena "cad2" en la cadena "cad1". Si la encuentra devuelve un puntero que apunta al primer carácter de la ocurrencia en "cad1", si no lo encuentra devuelve NULL. |
| strchr(cad, c) | Busca la primera ocurrencia del carácter contenido en la variable "c". Si lo encuentra devuelve un puntero que apunta al carácter encontrado en "cad", si no lo encuentra devuelve NULL. |
| strrchr(cad, c) | Busca la última ocurrencia del carácter contenido en la variable "c". Si lo encuentra devuelve un puntero que apunta al carácter encontrado en "cad", si no lo encuentra devuelve NULL. |
| strpbrk(cad1, cad2) | Busca la primera ocurrencia de cualquier carácter de la cadena "cad2" en la cadena "cad1". Si la encuentra devuelve un puntero que apunta al carácter encontrado en la cadena "cad1", si no lo encuentra devuelve NULL. |
Recorrido de Cadenas
Aquí mostramos distintas formas de recorrer un array de caracteres. La primera se basa en buscar el carácter de fin de cadena \0. En este ejemplo el bucle while recorre a - b - c (tres iteraciones). La segunda se basa en usar sizeof.
