Cadenas (parte III)

Hemos visto cómo obtener la longitud de una cadena, cómo copiar y cómo comparar cadenas. Estas son otras operaciones importantes:

Concatenación

La concatenación de cadenas es la operación de agregar una cadena al final de otra. Por ejemplo SOL + DADO = SOLDADO. Para hacer esto en C lo podemos hacer de una forma muy similar a la copia de cadenas, excepto que necesitamos un índice para cada cadena:

void concatena(char s[], char t[]) /* concatena t al final de s */
{
  int i = 0, j = 0;

  while (s[i]) /* busca el final de s */
    i++;
  while (s[i] = t[j]) { /* copia t al final de s */
    i++;
    j++;
  }
}

El segundo ciclo también se puede hacer así: while (s[i++] = t[j++]); ¿porqué?

Reverso de cadenas

El reverso de una cadena es simplemente la cadena escrita al revés. Por ejemplo, el reverso de AMOR es ROMA. Para hacer esto en C podemos tener un ciclo con dos variables de control, una que se mueve de izquierda a derecha desde el principio de la cadena y otra que se mueve de derecha a izquierda desde el final de la cadena, deteniéndose cuando ambas variables señalen al mismo caracter de la cadena:

void alreves(char s[]) /* voltea la cadena s */
{
  int i = 0, j = 0, t;

  while (s[j]) /* busca el final de s */
    j++;
  while (i < j) {
    t = s[i];
    s[i] = s[j];
    s[j] = t;
    i++;
    j--;
  }
}

Biblioteca estándar string.h

La mayoría de las funciones de cadenas que vimos en clase ya existen en la biblioteca estándar string.h, la cual ustedes pueden usar si agregan un #include <string.h> al principio de sus programas. Las funciones son las siguientes: strlen(s) regresa la longitud de la cadena s, strcpy(s, t) copia la cadena t en la cadena s, strcat(s, t) concatena la cadena t al final de la cadena s, strcmp(s, t) compara la cadena s y t regresando 0 si son iguales, un número positivo si s > t y un número negativo si s < t. La biblioteca estándar string.h contiene muchas más funciones de cadenas, pero no contiene, por ejemplo, una función que invierta una cadena.

Mayúsculas y minúsculas

Aunque no necesariamente una función de cadenas, sino de caracteres, es importante saber cómo decidir si una letra es mayúscula o minúscula o dígito, además de cómo convertir de mayúscula a minúscula y viceversa. Abajo suponemos que c es una variable que contiene un caracter:

if ('0' <= c && c <= '9') /* c es un digito */
if ('a' <= c && c <= 'z') /* c es una minuscula */
if ('A' <= c && c <= 'Z') /* c es una mayuscula */
c = c - 'a' + 'A' /* de minuscula a mayuscula */
c = c - 'A' + 'a' /* de mayuscula a minuscula */

Por supuesto, combinando algunas de las cosas anteriores se puede saber si c es una letra o un caracter alfanumérico, etc. Utilizando algunas de las instrucciones anotadas arriba, uno podría escribir una función que, por ejemplo, convierta una cadena de minúsculas a mayúsculas (sin cambiar ninguno de los caracteres que no sea una letra minúscula):

void mayuscula(char s[])
{
  int i = 0;

  while (s[i]) {
    if ('a' <= s[i] && s[i] <= 'z') /* solo modifica las minusculas */
      s[i] = s[i] - 'a' + 'A';
    i++
  }
}

Por supuesto, otras opciones son posibles y serán simples variantes de la función de arriba.