miércoles, 14 de noviembre de 2012

Cadena de caracteres

VIDEO MOTIVACIONAL




cadena de caracteres Introducción


Una cadena de caracteres es una secuencia de caracteres que termina con un carácter especial, que indica el final de la cadena, llamado carácter fin de cadena o carácter nulo. Se utilizan en C para almacenar y manipular texto.

El carácter fin de cadena tiene el código ASCII 0 (es el primero de la tabla ASCII) y se representa por
 ‘\0’.

Las cadenas de caracteres se representan en C como un texto delimitado por comillas dobles (
).
    • Ejemplo:
“Cadena ejemplo”
Aunque el carácter fin de cadena no aparece entre las comillas, está presente al final de la cadena. Internamente la cadena anterior tiene 15 caracteres (los 14 caracteres visibles más el carácter fin de cadena):

C
a
d
e
n
a
e
j
e
m
p
l
o
\0

    • Cuestión 1: ¿Cuántos caracteres tiene una cadena vacía: “”?

Las cadenas de caracteres se almacenan en vectores de caracteres (
arrays unidimensionales de tipo char).

Ejemplos de inicialización de cadenas de caracteres:
    • En el siguiente ejemplo se declara un vector de caracteres y se inicializa con la cadena de caracteres “hola”:
char texto[] = “hola”;
La variable texto tiene una longitud de 5 caracteres:
0
1
2
3
4
h
o
l
a
\0
    • También podemos inicializar un vector de caracteres especificando todos los caracteres individualmente, en este caso es necesario escribir explícitamente el carácter fin de cadena:
char texto[] = {‘h’, ‘o’, ‘l’, ‘a’, ‘\0’};
    • En el siguiente ejemplo se inicializa un vector de 14 caracteres con una cadena de menor tamaño:
char texto[14] = “hola”;
Los 5 primeros elementos de la variable texto se han inicializado con la cadena “hola”, el resto de elementos permanece sin inicializar. Puesto que el carácter fin de cadena ocupa un elemento del vector, la variable texto puede contener como máximo cadenas de 13 caracteres más el carácter fin de cadena.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
h
o
l
a
\0

    • También podemos inicializar un puntero a char con una cadena de caracteres:
char *p = "Cosa";
La variable p apunta al primer carácter de la cadena “Cosa”.

Arrays
 de cadenas de caracteres: Podemos definir los arrays de cadenas de caracteres de dos formas distintas:
    • Como una matriz de caracteres (array bidimensional de tipo char) en la que cada fila contiene una cadena diferente. Por ejemplo:
char cadenas[5][19] = {
     "Sumo con precisión",
     "Almaceno datos",
     "Dibujo gráficos",
     "Ejecuto programas",
     "Domino el C" };

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cadenas[0]
S
u
m
o
c
o
n
p
r
e
c
i
s
i
o
n
\0
cadenas[1]
A
l
m
a
c
e
n
o
d
a
t
o
s
\0
cadenas[2]
D
i
b
u
j
o
g
r
a
f
i
c
o
s
\0
cadenas[3]
E
j
e
c
u
t
o
p
r
o
g
r
a
m
a
s
\0
cadenas[4]
D
o
m
i
n
o
e
l
C
\0

Podemos acceder a las cadenas del array utilizando el índice de filas. Por ejemplo, para acceder a la tercera cadena se utiliza la siguiente expresión:
cadenas[2]
    • Como un vector de punteros a caracteres en el que cada elemento es un puntero que apunta al inicio de una cadena diferente. Por ejemplo:
char *cadenas[5] = {
     "Sumo con precisión",
     "Almaceno datos",
     "Dibujo gráficos",
     "Ejecuto programas",
     "Domino el C" };
Podemos acceder a las cadenas del array utilizando el índice del vector. Por ejemplo, para acceder a la primera cadena se utiliza la siguiente expresión:
cadenas[0]

Funciones de Entrada/Salida de cadenas de caracteres
Están definidas en la biblioteca de Entrada/Salida estándar stdio y sus prototipos se encuentran en el fichero de encabezamiento “stdio.h”:
#include <stdio.h>

Salida o escritura de cadenas de caracteres:
    • Estudiaremos dos funciones para la escritura de cadenas de caracteres por salida estándar: printf y puts
    • La función printf permite escribir una cadena de caracteres mediante el especificador de formato %s.
    • Ejemplo 5.1:
#include <stdio.h>
int main() {
   char nombre[20] = "Juan";
   char saludo[20] = "Buenas tardes";
   printf( "%s %s, hoy es tu %s.\n", saludo, nombre, "santo" );
   system(“pause”);
   return 0;
}
    • La función puts:
int puts( char *cadena );
Escribe el contenido del parámetro cadena por la salida estándar seguido de un salto de línea.
    • Ejemplo 5.2:
#include <stdio.h>
int main() {
    char mensaje[] = "Hola mundo";
    puts( mensaje );
    puts( "Hasta luego mundo" );
    system( “pause” );
    return 0;
}

Entrada o lectura de cadenas de caracteres:
    • Estudiaremos dos funciones para leer cadenas de caracteres de la entrada estándar: gets y scanf
    • La función scanf permite leer una palabra (una secuencia de caracteres delimitada por separadores) mediante el especificador de formato %s.
    •  Ejemplo 5.3: Ejecuta el siguiente programa y prueba a teclear tu nombre completo, incluyendo los apellidos.
#include <stdio.h>
int main() {
    char nombre[15]; /* Reservamos espacio para una cadena
                        de 14 caracteres + el caracter nulo */
    printf( "Escribe tu nombre: " );
    scanf( "%s", nombre );          /* Leemos el nombre */
    printf( "Hola %s.\n", nombre ); /* Escribimos la cadena */
    system( “pause” );
    return 0;
}
    • La función gets:
char *gets( char *cadena );
Lee una cadena de caracteres de la entrada estándar del sistema y la almacena en el parámetro cadena. Esta función lee caracteres hasta que encuentra un salto de línea (‘\n’) y los almacena todos en la cadena excepto el propio salto de línea.
La función gets devuelve la dirección de la cadena que se le pasa como parámetro si no hay errores, o NULL en caso contrario.
    • Ejemplo 5.4: Ejecuta el siguiente programa y prueba a teclear tu nombre completo, incluyendo los apellidos. Compara el resultado obtenido con el del Ejemplo-5.3.
#include <stdio.h>
int main() {
    char nombre[80] ; /* Reservamos espacio para cadena de
                         79 caracteres + el caracter nulo */
    printf( "Escribe tu nombre: " );
    gets( nombre );                 /* Leemos una linea de texto */
    printf( "Hola %s.\n", nombre );  /* Escribimos la cadena */
    system( “pause” );
    return 0;
}
Manipulación de cadenas de caracteres utilizando la biblioteca string

Los prototipos de las funciones de la biblioteca
 string se encuentran en el fichero de encabezamiento “string.h”
#include <string.h>

Longitud de una cadena:
unsigned int strlen( char *cad );
    • Devuelve la longitud de la cadena de caracteres que se le pasa como parámetro, excluyendo el carácter de fin de cadena (carácter nulo '\0').
    • Ejemplo 5.5: Compila y ejecuta el siguiente programa.
#include <stdio.h>
#include <string.h>
int main() {
    char palabra[20];
    printf( "Teclea una palabra: " );
    scanf( "%s", palabra );
    printf( "La longitud de %s es %u\n", palabra, strlen( palabra ) );
    system( “pause” );
    return 0;
}


Copia de cadenas:
char *strcpy( char *destino, char *fuente );
    • La función strcpy copia el contenido de fuente en destino (ambos parámetros son cadenas de caracteres).
    • El parámetro destino debe tener espacio suficiente para almacenar la cadena fuente.
    • Ejemplo 5.6: Escribe una función llamada dia_semana que calcule el día de la semana a partir de un valor comprendido entre 1 y 7, donde el valor 1 corresponde al lunes y el 7 al domingo. La función recibe dos parámetros: un valor de tipo entero sin signo y un vector de caracteres donde almacenará el nombre del día de la semana. Si el valor recibido no está comprendido entre 1 y 7, la función almacenará la cadena “Dia incorrecto” en el vector de caracteres.
#include <string.h>

void dia_semana( unsigned int dia, char nombre[] )
{
    char *nombre_dias[] = {
        "Lunes",
        "Martes",
        "Miercoles",
        "Jueves",
        "Viernes",
        "Sabado",
        "Domingo" };
    if (dia >= 1 && dia <= 7)
        strcpy( nombre, nombre_dias[dia-1] );
    else
        strcpy( nombre, "Dia incorrecto" );
}
    • Ejemplo de uso de la función dia_semana:
int main() {
    char fecha[30];
    dia_semana( 3, fecha );
    printf( "El dia 3 es: %s\n", fecha );
    dia_semana( 9, fecha );
    printf( "El dia 9 es: %s\n", fecha );
    system( “pause” );
    return 0;
}
    • Ejercicio: Escribe una función llamada nombre_mes que calcule el nombre del mes a partir de un valor entero comprendido entre 1 y 12. El prototipo de la función es el siguiente:
void nombre_mes( unsigned int mes, char merror[], char nombre[] );
La función debe almacenar en el parámetro nombre el nombre del mes correspondiente al valor mes. En caso de que el valor de mes sea incorrecto, la función debe copiar el contenido del parámetro merror en el parámetro nombre. Para probar tu función, utiliza la siguiente función main y prueba a introducir valores correctos e incorrectos cuando ejecutes el programa:
int main() {
    char mes[30];
    unsigned m;
    printf( “Escribe el número de mes: “ );
    scanf( “%u”, &m );
    nombre_mes( m, “Número incorrecto”, mes );
    printf( “El mes %u es %s\n”, m, mes );
    system( “pause” );
    return 0;
}

Concatenación de cadenas:
char *strcat( char *destino, char *fuente );
    • La función strcat concatena la cadena fuente con la cadena destino, es decir, copia la cadena fuente al final de la cadena destino. Por ejemplo, en el siguiente programa, la variable resultado contiene inicialmente la cadena “otorrino”; sin embargo, después de ejecutar la función strcat, dicha variable contendrá la cadena “otorrinolaringólogo”, que se mostrará en la pantalla:
int main() {
    char resultado[80] = “otorrino”;
    strcat( resultado, “laringólogo” );
    printf( “%s\n”, resultado );
}
    • El parámetro destino debe tener espacio suficiente para almacenar la concatenación de ambas cadenas.
    • Ejemplo 5.7: En Windows, la ubicación y el nombre de los archivos se especifican mediante la unidad, la ruta de acceso, el nombre y la extensión. Por ejemplo, el archivo “d:\documentos\cartas\bienvenida.doc” se encuentra en la unidad “d:”, en la ruta de acceso “\documentos\cartas”, su nombre es “bienvenida” y su extensión “doc”. Escribe un programa que pida por teclado la unidad y el nombre base de un archivo, y que le añada la ruta de acceso “\Mis imagenes\” y la extensión “.jpg”. El resultado debe imprimirse en pantalla y guardarse en una cadena de caracteres. Debes tener en cuenta que, en C, el carácter ‘\’ se representa como una barra doble ‘\\’.
#include <stdio.h>
#include <string.h>

#define MAX_LONG 100

int main() {
    char unidad[10];
    char nombre[30];
    char nombre_completo[MAX_LONG];
    printf( "Escriba la letra de la unidad: " );
    scanf( "%s", unidad );
    printf( "Escriba el nombre del fichero: " );
    scanf( "%s", nombre );
    if (strlen(unidad) + strlen(nombre)
        + strlen(":\\Mis imagenes\\") + strlen(".jpg") + 1 <= MAX_LONG)
    {
        strcpy( nombre_completo, unidad );
        strcat( nombre_completo, ":\\Mis imagenes\\" );
        strcat( nombre_completo, nombre );
        strcat( nombre_completo, ".jpg" );
        printf( "El nombre completo es \"%s\"\n", nombre_completo );
    }else
        puts( "No hay espacio suficiente." );

    system( “pause” );
    return 0;
}
    • Ejercicio: Escribe una función llamada genera_nombre que, a partir de los dos apellidos y el nombre de una persona, calcule el nombre completo con el siguiente formato: “apellido1 apellido2, nombre”. La función recibe tres parámetros de tipo cadena de caracteres que contienen el nombre, el primer apellido y el segundo apellido respectivamente. El resultado lo almacena en un cuarto parámetro de tipo cadena de caracteres que tendrá una lóngitud de 100 caracteres. Utiliza la siguiente función main para comprobar que tu función es correcta:
int main() {
    char nombre_completo[100];
    genera_nombre( “Juan”, “Fuentes”, “Soleadas”, nombre_completo );
    printf( “%s\n”, nombre_completo );
    system( “pause” );
    return 0;
}

Comparación de cadenas:
int strcmp( char *cad1, char *cad2 );
    • La función strcmp compara alfabéticamente las dos cadenas que se le pasan como parámetros. Devuelve un valor numérico que nos indica el resultado de la comparación según la siguiente tabla:
Valor devuelto
Significado
Menor que 0
cad1 es anterior que cad2
0
cad1 es igual que cad2
Mayor que 0
cad1 es posterior que cad2
    • Ejemplo 5.8: Escribe un programa que lea del teclado una palabra y muestre un mensaje por pantalla indicando si dicha palabra es anterior, igual o posterior que la palabra “universo”.
#include <string.h>
int main() {
    char cad[80];
    printf( "Escribe una palabra: " );
    scanf( "%s", cad );
    if (strcmp( cad, "universo" ) == 0)
        printf( "La palabra es \"universo\".\n" );
    else if (strcmp( cad, "universo" ) < 0)
        printf( "La palabra %s es anterior que \"universo\".\n", cad );
    else if (strcmp( cad, "universo" ) > 0)
        printf( "La palabra %s es posterior que \"universo\".\n", cad );

    /* Nota: La última sentencia "if" no es necesaria puesto que
        llegados a ese punto ya sabemos que "strcmp" devuelve un
        valor mayor que cero. Se ha añadido simplemente para
        ilustrar el uso de strcmp. La forma más apropiada de
        escribir dichas sentencias "if" anidadas es la siguiente:

        if (strcmp( cad, "universo" ) == 0)
            printf( "La palabra es \"universo\".\n" );
        else if (strcmp( cad, "universo" ) < 0)
            printf( "La palabra %s es anterior que \"universo\".\n", cad );
        else
            printf( "La palabra %s es posterior que \"universo\".\n", cad );
    */
   
    system( “pause” );
    return 0;
}
    • Ejercicio: Escribe un programa que solicite por teclado dos cadenas de caracteres y las muestre por pantalla ordenadas alfabéticamente.
Manipulación de cadenas carácter a carácter

Recorrido secuencial de los caracteres de una cadena:
    • Para recorrer todos los caracteres de una cadena desde el principio hasta el final, debemos comenzar por el carácter de índice 0 e ir incrementando el índice hasta encontrar el carácter fin de cadena (carácter nulo).
    • Ejemplo 5.9: Escribe una función que cuente los caracteres de una cadena que se le pasa como parámetro y devuelva el número de caracteres que contiene excluyendo el carácter fin de cadena.
unsigned int long_cad( char cadena[] ) {
    unsigned int i = 0;
    while (cadena[i] != '\0')
        i++;
    return i;
}
    • Ejemplo de uso de long_cad: Usando la función del ejemplo anterior, imprime el número de caracteres de la frase “Dábale arroz a la zorra el abad”.
int main() {
    printf( "La frase tiene %u caracteres.\n",
        long_cad( "Dábale arroz a la zorra el abad" ) );
    system( “pause” );
    return 0;
}
    • Ejercicio: Escribe una función llamada escribe_cad que se comporte del modo similar que la función puts. Es decir, la función recibe una cadena de caracteres como parámetro y la muestra por salida estándar seguida de un salto de línea (carácter '\n'). Utilice la función putchar para escribir caracteres por salida estándar. Esta función se encuentra definida en el fichero de encabezamiento “stdio.h” y recibe como parámetro un carácter. Para probar tu función puedes utilizar el Ejemplo 5.2, cambiando las llamadas a la función puts por escribe_cad, tal como se muestra en el siguiente código:
int main() {
    char mensaje[] = "Hola mundo";
    escribe_cad( mensaje );
    escribe_cad( "Hasta luego mundo" );
    system( "pause" );
    return 0;
}

Construcción de cadenas:
    • Cuando construimos una cadena carácter a carácter debemos recordar que hay que marcar el final de cadena con el carácter fin de cadena (carácter nulo'\0').
    • Ejemplo 5.10: Escribe una función que copie una cadena de caracteres en otra, transformando en mayúsculas las iniciales de cada palabra. El prototipo de la función es el siguiente:
void iniciales_may( char destino[], char fuente[] );
La función transforma la cadena que se le pasa en el parámetro fuente y la almacena en el parámetro destino. Para simplificar el problema, supondremos que las cadenas sólo contienen letras y espacios.
Para convertir un carácter de minúsculas a mayúsculas, puedes utilizar la función toupper que se encuentra definida en el fichero de encabezamiento“ctype.h”. Esta función recibe como parámetro un carácter y devuelve el carácter correspondiente en mayúsculas.
#include <ctype.h>
void iniciales_mays( char destino[], char fuente[] ) {
    char caracter_anterior = ' ';
    int i;
    for (i=0; fuente[i] != '\0'; i++) {
        if (caracter_anterior == ' ' && fuente[i] >= 'a' && fuente[i] <= 'z')
            destino[i] = toupper( fuente[i] );
        else
            destino[i] = fuente[i];
        caracter_anterior = fuente[i];
    }
    destino[i] = '\0'; /* Marcamos el final de la cadena destino. */
}
    • Ejemplo de uso de iniciales_may:
void main() {
    char texto[200];
    iniciales_mays( texto, "guiones de practicas" );
    printf( "%s\n", texto );
    system( “pause” );
    return 0;
}
    • Ejercicio: Modifique la función anterior para que almacene en el parámetro destino el acrónimo de la cadena que se le pasa en el parámetro fuente. Por ejemplo, si la cadena fuente es “Sociedad española de transportistas autónomos”, la función almacenará en la cadena destino “SEDTA”. Puede probar la función con el ejemplo de uso utilizado para la función iniciales_mays.

Concatenación de cadenas:
    • Para añadir caracteres al final de una cadena debemos insertar los nuevos caracteres a partir de la posición donde se encuentre el carácter fin de cadena (carácter nulo '\0').
    • Ejemplo 5.11: Escriba una función llamada strcat_mays que se comporte de modo similar que la función strcat pero convirtiendo a mayúsculas la cadena fuente. Para convertir los caracteres de minúsculas a mayúsculas puedes utilizar la función toupper descrita en el ejemplo anterior.
#include <ctype.h>
char *strcat_mays( char destino[], char fuente[] ) {
    int i = 0;
    int j;
    while (destino[i] != '\0') i++;
    for (j=0; fuente[j] != '\0'; j++) {
        if (fuente[j] >= 'a' && fuente[j] <= 'z')
            destino[i+j] = toupper(fuente[j]);
        else
            destino[i+j] = fuente[j];
    }
    destino[i+j] = '\0';
    return destino;
}
    • Ejemplo de uso de strcat_mays:
int main() {
    char texto[100] = "";
    strcat_mays( texto, "esto es " );
    puts( texto );
    strcat_mays( texto, "una PRUeba." );
    puts( texto );
    system( “pause” );
    return 0;
}



laboratorio 10 
Realizar un programa que te pida tu nombre y lo muestre en pantalla sepando cada letra de la siguiente son un espacio.  Por ejemplo, si tu nombre es "JUAN", debería aparecer en pantalla " J U A N "