lunes, 10 de junio de 2013

Cadenas (Unidad 7)

INTRODUCCIÓN


Se pueden hacer inicializaciones de arreglos de caracteres en donde automáticamente C asigna el caracter nulo al final de la cadena, de la siguiente forma:
char nombre_arr[ tam ]="cadena";
Por ejemplo, el siguiente fragmento inicializa cadena con ``hola'':
char cadena[5]="hola";

El código anterior es equivalente a:
char cadena[5]={'h','o','l','a','\0'};

Para asignar la entrada estándar a una cadena se puede usar la función scanf con la opción %s(observar que no se requiere usar el operador &), de igual forma para mostrarlo en la salida estándar.
Por ejemplo:
main()
{
    char nombre[15], apellidos[30];

    printf("Introduce tu nombre: ");
    scanf("%s",nombre);
    printf("Introduce tus apellidos: ");
    scanf("%s",apellidos);
    printf("Usted es %s %s\n",nombre,apellidos);
}
El lenguaje C no maneja cadenas de caracteres, como se hace con enteros o flotantes, por lo que lo siguiente no es válido:
main()
{
    char nombre[40], apellidos[40], completo[80];

    nombre="José María";                /* Ilegal */
      apellidos="Morelos y Pavón";        /* Ilegal */
      completo="Gral."+nombre+appellidos; /* Ilegal */
}


CADENAS


FUNDAMENTOS DE CADENAS Y CARACTERES

Los caracteres son bloques de construcción fundamentales para los programas fuente. Un programa puede contener constantes de carácter. Una constante de carácter es un valor int representado por un carácter entre comillas sencillas. El valor de una constante de carácter es el valor entero del carácter en el conjunto de caracteres de la máquina.
Por ejemplo, 'z' representa el valor entero de z, y '\n' representa el valor entero de una nueva línea.
Una cadena es un conjunto de caracteres tratados como una sola unidad. Una cadena puede incluir letras, dígitos y varios caracteres especiales como +, -, *, y $. En C, las literales de cadena, o constantes de cadena, se escriben dentro de comillas dobles de la siguiente manera:
“Juan P. Pérez” (un nombre)
“99999 de Eje Central” (la dirección de una calle)
En C, una cadena es un arreglo de caracteres, los cuales terminan con el carácter nulo ('\0'). Se accede a una cadena mediante un apuntador a su primer carácter. El valor de una cadena es la dirección del primer carácter. Así, en C, es apropiado decir que una cadena es un apuntador, de hecho, un apuntador al primer carácter de la cadena. En este sentido, las cadenas son como arreglos, debido a que un arreglo también es un apuntador al primer elemento.
Un arreglo de caracteres o una variable de tipo char * puede inicializarse con una cadena en la definición. Las definiciones
char color[] = “azul”;
const char *ptrColor = “azul”;
inicializan una variable con la cadena “azul”. La primera definición crea un arreglo de 5 elementos, color, que contiene los caracteres 'a', 'z', 'u', 'l' y '\0'. La segunda variable crea una variable apuntador, ptrColor, que apunta a la cadena “azul” en algún lugar de la memoria.
La definición del arreglo anterior también podría escribirse como
char color[] = {'a', 'z', 'u', 'l', '\0'};
Cuando se define un arreglo para que contenga una cadena, éste debe ser lo suficiente grande para almacenar la cadena y su carácter de terminación nulo. La definición anterior determina automáticamente el tamaño del arreglo, basándose en el número de inicializaciones de la lista de inicialización ('a', 'z', 'u', 'l', '\0').
No almacenar suficiente espacio en un arreglo de caracteres para almacenar el carácter nulo que termina una cadena, es un error.
Si una cadena es más grande que el arreglo de caracteres en el cual se va a almacenar, los caracteres más allá del final del arreglo sobrescribirán los datos siguientes en la memoria del arreglo.
Una cadena puede almacenarse en un arreglo, por medio de scanf. Por ejemplo, la siguiente instrucción almacena el arreglo de caracteres palabra[20]:
scanf( “%s”, palabra );
La cadena que introduce el usuario se almacena en palabra. Observe que palabra es un arreglo, el cual es, por supuesto, un apuntador, de modo que no necesitamos un & con el argumento palabra. La función scanf leerá caracteres hasta encontrar un espacio, un tabulador, un indicador de nueva línea o de fin de archivo. Observe que la cadena no debe ser mayor que 19 caracteres para dejar espacio suficiente para el carácter de terminación nulo. Para un arreglo de caracteres que se imprimirá como una cadena, el arreglo debe contener el carácter de terminación nulo.
La cadena de caracteres está definida como un arreglo de caracteres, debido a que el nombre de un arreglo es la dirección de memoria del primer elemento del arreglo, por lo que si se iguala el nombre del arreglo al nombre de un puntero, a este puntero se le puede aplicar aritmética de punteros (ver apunte Punteros) para poder desplazarse entre los datos del arreglo.
Las funciones scanf() y printf() reconocen a los espacios introducidos con la barra espaciadora como finales de cadena. Esto puede solucionarse usando las funciones gets() y puts() incluidas en la librería ctype.h.

FUNCIONES DE MANEJO DE CADENAS Y CARACTERES

La biblioteca de manipulación de cadenas (<string.h>) proporciona muchas funciones útiles para manipular datos de cadenas (copiar y concatenar cadenas), comparar cadenas, buscar caracteres y otras cadenas dentro de cadenas, separar cadenas en tockens (separar cadenas en sus piezas lógicas) y determinar la longitud de cadenas. Vamos a ver algunas de ellas.
char *strcpy (char *s1, const char *s2) Copia la cadena s2 dentro del arreglo s1. Devuelve el valor de s1.
char *strncpy (char *s1, const char *s2, size_t n) Copia al menos n caracteres de la cadena s2 dentro del arreglo s1. Devuelve el valorde s1n.
char *strcat (char *s1, const char *s2) Agrega la cadena s2 al arreglo s1. El primer carácter de s2 sobrescribe al carácter de terminación nulo de s1. Devuelve el valor de s1.
char *strcat (char *s1, const char *s2, size_t n) Agrega al menos n caracteres de la cadena s2 al arreglo s1. El primer carácter de s2 sobrescribe al carácter de terminación nulo de s1. Devuelve el valor de s1.
®    En la función strcpy, s1 (un arreglo de caracteres) debe ser lo suficientemente grande para almacenar la cadena s2 y el carácter de terminación nulo, el cual también se copia.
®    Observe que en la función strncpy, un carácter de terminación nulo se escribe solamente si el número de caracteres a copiar (en s1) es al menos mayor en uno que la longitud de la cadena (s2). Por ejemplo, si “prueba” es el segundo argumento, se escribe un carácter de terminación nulo sólo si el tercer argumento de strncpy, es al menos 7 (seis caracteres en “prueba” más el carácter de terminación nulo). Si el tercer argumento es mayor que 7, el carácter nulo se agrega al arreglo hasta que se escriben el número total de caracteres especificados en el tercer argumento.
®    Al usar la función srtcat, el primer carácter del segundo argumento remplaza el nulo ('\0') que termina la cadena del primer argumento. El programador debe asegurarse de que el arreglo utilizado para almacenar la primera cadena es lo suficientemente grande para almacenar la primera cadena, la segunda cadena y el carácter de terminación nulo copiado desde la segunda cadena.
®    La función strncat agrega un carácter de terminación nulo automáticamente al resultado.
Un error común de programación es no agregar el carácter de terminación nulo al primer argumento de strncpy, cuando el tercer argumento es menor o igual que la longitud de la cadena del segundo argumento.
Podemos utilizar strcpy para copiar la cadena completa del arreglo x dentro del arreglo y, y utiliza strncpy para copiar los primeros 14 caracteres del arreglo x dentro del arreglo z. Se agrega un carácter nulo ('\n') al arreglo z, debido a que la llamada a strncpy en el programa no escribe un carácter de terminación nulo (el tercer argumento es menor que la longitud de la cadena del segundo argumento).
Aunque C no incorpora en su definición operadores para el manejo de cadenas de caracteres, todo compilador de C proporciona una librera estándar (string.h) con funciones para facilitar su utilización. Destacar algunas de ellas:
strcpy: La función strcpy se encuentra en la biblioteca <string.h> y se utiliza para copiar una cadena de caracteres (fuente) en el lugar que ocupaba otra (destino). Esta copia es destructiva, o sea, que todos los caracteres que estaban en la cadena destino desaparecen, aunque la cadena destino fuera más larga que la cadena fuente .La cadena destino se pone como primer argumento de la función y la cadena fuente como segundo. Vamos a verlo con un ejemplo.
#include<stdio.h>
#include<string.h>
 
int main() 
{
    char texto1[]="corta"; 
    char texto2[]="mediana"; 
    char texto3[]="larguisima";
 
    strcpy(texto2,texto1); 
    printf("%s\n",texto2); 
    strcpy(texto2,texto3); 
    printf("%s\n",texto2); 
 
return 0; 
}       

strcat: En el programa anterior vimos que la función strcpy es desctructiva, pero hay otra función en la librería <string.h> que copia una cadena (fuente) en otra (destino) sin destruir ésta, es decir, que copia una cadena detrás de la otra esta función es conocida como strcat. Vamos a hacer un ejemplo:

#include<stdio.h> 
#include<string.h>
int main()
{
    char texto1[]="Don Pepito"; 
    char texto2[]=" y "; 
    char texto3[]="Don Jose";printf("%s\n",texto1);
 
    strcat(texto1,texto2);
    printf("%s\n",texto2);  
    strcat(texto1,texto3); 
    printf("%s\n",texto2);
    getchar(); 
return 0; 
}       

strlen: esta función devuelve el total (entero) de caracteres que conforman una cadena (excluyendo el caracter nulo \0). Vamos a hacer un ejemplo:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#define MAXLON 80
 
int main(void)
{
    char a[MAXLON+1];
    int longitud;
    
    clrscr(); 
    printf ("Introduce una cadena (max. %d caracteres): ", MAXLON);
    scanf("%s",&a); 
    longitud = strlen(a);
    printf ("\nLongitud de la cadena: %d\n", longitud);
    getch();
return 0; 
}
 
strcmp: strcmp (abreviatura de ((string comparison))). La función strcmp recibe dos cadenas, a y b, devuelve un entero. El entero que resulta de efectuar la llamada strcmp(a, b) codifica el resultado de la comparación:
es menor que cero si la cadena a es menor que b,
es 0 si la cadena a es igual que b, y
es mayor que cero si la cadena a es mayor que b.
Naturalmente, menor significa que va delante en orden alfabético, y mayor que va detrás.
#include <stdio.h> 
#include <string.h>
int main() 
{
    char s1[6] = "Abeja"; 
    char s2[6] = "abeja"; 
    int i;
    
    printf( "s1=%s\t", s1 ); 
    printf( "s2=%s\n", s2 );
    
    i = strcmp( s1, s2 ); 
    printf( "s1 es " );
    if( i < 0 ) printf( "menor que" );
    else if( i > 0 ) printf( "mayor que" );
    else printf( "igual a" ); 
    printf( " s2\n" );
 
return 0; 
}
            
 
No sólo string.h contiene funciones útiles para el tratamiento de cadenas. En ctype.h se encuentran unas funciones que permiten hacer cómodamente preguntas acerca de los caracteres, como si son mayúsculas, minúsculas, dígitos, etc:
      isalnum(caracter): devuelve cierto (un entero cualquiera distinto de cero) si caracter es una letra o dígito, y falso (el valor entero 0) en caso contrario.
      isalpha(caracter): devuelve cierto si caracter es una letra, y falso en caso contrario.
      isblank(caracter): devuelve cierto si caracter es un espacio en blanco o un tabulador.
      isdigit(caracter) devuelve cierto si caracter es un digito, y falso en caso contrario.
      isspace(caracter): devuelve cierto si caracter es un espacio en blanco, un salto de línea, un retorno de carro, un tabulador, etc., y falso en caso contrario.
      islower(caracter): devuelve cierto si caracter es una letra minúscula, y falso en caso contrario.
      isupper(caracter): devuelve cierto si caracter es una letra mayúscula, y falso en caso contrario.
      toupper(caracter): devuelve la mayúscula asociada a caracter, si la tiene; si no, devuelve el mismo caracter.
      tolower(caracter): devuelve la minúscula asociada a caracter, si la tiene; si no, devuelve el mismo caracter.

CONCLUSIÓN



A diferencia de otros lenguajes de programación que emplean un tipo denominado cadena string para manipular un conjunto de símbolos, en C, se debe simular mediante un arreglo de caracteres, en donde la terminación de la cadena se debe indicar con nulo. Un nulo se especifica como '\0'. Por lo anterior, cuando se declare un arreglo de caracteres se debe considerar un carácter adicional a la cadena más larga que se vaya a guardar. Por ejemplo, si se quiere declarar un arreglo cadena que guarde una cadena de diez caracteres.

No hay comentarios:

Publicar un comentario