15 - Funciones que facilitan el trabajo con cadenas de caracteres (string.h)


Hemos visto en el concepto anterior que en el lenguaje C para trabajar con cadenas de caracteres debemos definir un vector de caracteres de un tamaño definido, por ejemplo:

char palabra[31];

En la línea anterior estamos definiendo un vector de caracteres que nos permite almacenar hasta 30 caracteres (recordar que una posición del vector se requiere para el terminador de cadena '\0')

Desarrollamos anteriormente un algoritmo para contar la cantidad de letras que almacena una cadena de caracteres, básicamente recorrimos mediante un while y contamos cada caracter hasta que encontramos el terminador de cadena '\0'.

Hay muchos algoritmos de uso común para trabajar con cadenas de caracteres, el lenguaje C viene con un conjunto de funciones que nos permiten administrar las cadenas de caracteres.

Para facilitar el trabajo con las cadenas de caracteres debemos incluir el archivo string.h y a partir de esto usar sus funcionalidades:

#include<string.h>

función: strlen

Problema 1:

Ingresar por teclado una palabra. Mostrar luego por pantalla la cantidad de letras que tiene.

Programa: programa77.c

Ver video

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char palabra[31];
    printf("Ingrese una palabra:");
    gets(palabra);
    int cant=strlen(palabra);
    printf("La palabra %s tiene %i letras",palabra,cant);
    getch();
    return 0;
}

Lo primero que hacemos ahora es incluir los archivos stdio.h, conio.h y string.h:

#include<stdio.h>
#include<conio.h>
#include<string.h>

La función strlen se le pasa como parámetro una variable de tipo cadena de caracteres (vector de tipo char) y nos retorna un entero que representa la cantidad de caracteres almacenados en dicha cadena:

    int cant=strlen(palabra);

El valor devuelto por la función strlen se carga en la variable cant que procedemos a mostrarla seguidamente:

    printf("La palabra %s tiene %i letras",palabra,cant);

Tener en cuenta que la llamada a la función strlen nos evita implementar el while con el contador de caracteres:

#include<stdio.h>
#include<conio.h>

int main()
{
    char palabra[31];
    printf("Ingrese una palabra:");
    gets(palabra);
    int cant=0;
    while (palabra[cant]!='\0')
    {
        cant++;
    }
    printf("La palabra %s tiene %i letras",palabra,cant);
    getch();
    return 0;
}

Imaginemos si tenemos que calcular la cantidad de caracteres de muchas cadenas durante un programa.

función: strcmp

Hasta ahora no desarrollamos programas que comparen el contenido de dos cadenas de caracteres. Lo primero que hay que decir que no están definidos los operadores relacionales ==, >, < etc.

Es incorrecto tratar de comparar si dos cadenas son iguales.

if (nombre1==nombre2)
{
    printf("Son iguales los nombres")
}

Podemos implementar nosotros un análisis dentro de un while y comparar caracter a caracter, pero este algoritmo no es tan fácil y cómodo de implementar cada vez que tenemos que comparar dos cadenas.

Entonces el lenguaje C tiene otra función llamada strcmp que le pasamos dos cadenas a comparar y nos retorna un entero:

int strcmp(cadena1,cadena2)

Retorna un cero si las dos cadenas son exactamente iguales.

Retorna un valor mayor a cero si la cadena1 es mayor alfabéticamente que la segunda.

Retorna un valor menor a cero si la cadena2 es mayor alfabéticamente que la primera.

Problema 2:

Ingresar dos nombres por teclado. Mostrar un mensaje si son iguales y sino mostrar el que es mayor alfabéticamente.

Programa: programa78.c

Ver video

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre1[31];
    char nombre2[31];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);
    if (strcmp(nombre1,nombre2)==0)
    {
        printf("Los dos nombres son iguales");
    }
    else
    {
        if (strcmp(nombre1,nombre2)>0)
        {
            printf("%s es mayor alfabeticamente",nombre1);
        }
        else
        {
            printf("%s es mayor alfabeticamente",nombre2);
        }
    }
    getch();
    return 0;
}

Primero definimos dos vectores de caracteres y los cargamos por teclado:

    char nombre1[31];
    char nombre2[31];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);

Para controlar si los dos nombres son iguales verificamos si la función strcmp retorna un cero:

    if (strcmp(nombre1,nombre2)==0)
    {
        printf("Los dos nombres son iguales");
    }

En el caso que retorne un valor mayor a cero significa que el primer nombre es mayor alfabéticamente:

        if (strcmp(nombre1,nombre2)>0)
        {
            printf("%s es mayor alfabeticamente",nombre1);
        }

Funcionamiento interno de strcmp.

Definimos dos cadenas de 7 elementos y las inicializamos:

	char cadena1[7]="Bien";
	char cadena2[7]="Bueno";

El contenido de las componente de cada una de las cadenas es el siguiente:

componente	[0]	[1]	[2]	[3]	[4]	[5]	[6]
cadena1	        ‘B’	‘i’	‘e’	‘n’	‘\0’
cadena2	        ‘B’	‘u’	‘e’	‘n’	‘o’	‘\0’

El contenido de las componente de cada una de las cadenas (en valores ASCII) es el siguiente:

componente	[0]	[1]	[2]	[3]	[4]	[5]	[6]
cadena1	        66	105	101	110	0
cadena2	        66	117	101	110	111	0

Seguidamente llamamos a la función strcmp, la cual devuelve un valor entero que le asignamos a una variable resultado:

	int resultado=strcmp(cadena1,cadena2);

Internamente la función hace lo siguiente:
Resta al valor ASCII de la primer componente de cadena1 (66) el valor de la primer componente de cadena2 (66). Como el resultado es cero (0), continúa con la siguiente componente. Resta al valor de la segunda componente de cadena1 (105) el valor de la segunda componente de cadena2 (117), como el resultado es diferente de cero no sigue comparando y devuelve ese valor (-12):

componente	[0]	[1]	[2]	[3]	[4]	[5]
cadena1	        66	105	101	110	0
cadena2	        66	117	101	110	111	0
Resultado	 0	-12

Esa es la explicación de porque strcmp retorna 0 si son iguales las dos cadenas y un valor mayor a 0 si la primer cadena es mayor a la segunda y viceversa.

función: strcpy

Hemos visto que si necesitamos comparar dos string (string es sinónimo de cadenas de caracteres o vectores) no tenemos disponibles los operadores relacionales ==, > etc.
Si necesitamos copiar un string en otro tampoco funciona el operador de asignación =, para resolver este problema el lenguaje C nos proporciona la función srtcpy.

La función strcpy tiene dos parámetros de tipo string, al primer parámetro se le copia el string del segundo parámetro:

strcpy(cadena1,cadena2)

Es decir que en cadena1 se copia el contenido de cadena2, si ya tenía información previa cadena1 se le borra el contenido anterior.

Problema 3:

Cargar por teclado dos nombres de personas que tengan distinta cantidad de caracteres. Almacenar en un tercer vector de caracteres el nombre que tenga más caracteres. Luego imprimir dicho vector.

Programa: programa79.c

Ver video

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre1[31];
    char nombre2[31];
    char nombreLargo[31];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);
    if (strlen(nombre1)>strlen(nombre2))
    {
        strcpy(nombreLargo,nombre1);
    }
    else
    {
        strcpy(nombreLargo,nombre2);
    }
    printf("El nombre %s tiene mas caracteres",nombreLargo);
    getch();
    return 0;
}

Definimos tres string, dos los cargamos por teclado y el tercero lo inicializamos mediante la función strcpy:

    char nombre1[31];
    char nombre2[31];
    char nombreLargo[31];

Mediante la función strlen verificamos cual de los dos string tiene más caracteres y copiamos en la variable de tipo string nombreLargo el contenido de nombre1 o nombre2 según corresponda:

    if (strlen(nombre1)>strlen(nombre2))
    {
        strcpy(nombreLargo,nombre1);
    }
    else
    {
        strcpy(nombreLargo,nombre2);
    }

Tener en cuenta que no existe la asignación:

nombreLargo=nombre1;

Si en un problema necesitamos dejar un string vacío podemos utilizar la función strcpy pasando un string sin caracteres (no debe haber ni un espacio en blanco):

strcpy(cadena,"");

Otra forma de hacer lo mismo sin utilizar la función strpy es asignar el terminador de cadena a la primer posición del string:

cadena[0]='\0';

función: strcat

Si necesitamos agregar a un string otro string podemos utilizar la función strcat.

La función strcat tiene dos parámetros de tipo string, al primer parámetro se le añade o agrega al final el string del segundo parámetro, es obligatorio que el primer parámetro esté inicializado:

strcat(cadena1,cadena2)

Problema 4:

Cargar por teclado en dos variables de tipo string el nombre y el apellido de una persona. Definir un tercer string y guardar la concatenación del nombre y apellido.

Programa: programa80.c

Ver video

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre[31];
    char apellido[31];
    char nomape[62];
    printf("Ingrese el nombre:");
    gets(nombre);
    printf("Ingrese el apellido:");
    gets(apellido);
    strcpy(nomape,nombre);
    strcat(nomape," ");
    strcat(nomape,apellido);
    printf("%s",nomape);
    getch();
    return 0;
}

Definimos dos variables donde almacenar el nombre y apellido:

    char nombre[31];
    char apellido[31];

Como sabemos podemos guardar como máximo 30 caracteres en el nombre y 30 caracteres en el apellido, luego el string que almacenará los dos datos juntos más un espacio en blanco entre el nombre y apellido debe reservar espacio para 62 caracteres:

    char nomape[62];

Luego de cargar los dos string primero copiamos en la variable nomape el nombre de la persona empleando la función strcpy:

    strcpy(nomape,nombre);

Seguidamente le agregamos al string nomape un string con un único caracter:

    strcat(nomape," ");

Y por último le agregamos el string con el apellido:

    strcat(nomape,apellido);

Cuando ejecutamos el programa podemos ver que al imprimir la variable nomape aparecen todos los datos cargados en las variables nombre y apellido con un espacio de separación:

strcat

Problemas propuestos

Solución
programa81.c

#include<conio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char usuario[30];
    char clave[30];
    printf("Ingrese el nombre de usuario:");
    gets(usuario);
    printf("Ingrese la clave:");
    gets(clave);
    if (strcmp(clave,"abc123")==0)
    {
        printf("La clave ingresada es correcta");
    }
    else
    {
        printf("La clave ingresada es incorrecta");
    }
    getch();
    return 0;
}




programa82.c

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre1[30];
    char nombre2[30];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);
    printf("Nombres ordenados alfabeticamente\n");
    if (strcmp(nombre1,nombre2)<0)
    {
        printf("%s %s",nombre1,nombre2);
    }
    else
    {
        printf("%s %s",nombre2,nombre1);
    }
    getch();
    return 0;
}




programa83.c

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre1[30];
    char nombre2[30];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);
    if (strlen(nombre1)>strlen(nombre2))
    {
        printf("%s\n%s",nombre1,nombre2);
    }
    else
    {
        printf("%s\n%s",nombre2,nombre1);
    }
    getch();
    return 0;
}




programa84.c

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main()
{
    char nombre1[31];
    char nombre2[31];
    char nombre3[31];
    char total[93];
    printf("Ingrese primer nombre:");
    gets(nombre1);
    printf("Ingrese segundo nombre:");
    gets(nombre2);
    printf("Ingrese tercer nombre:");
    gets(nombre3);
    if (strcmp(nombre1,nombre2)<0 && strcmp(nombre1,nombre3)<0)
    {
        strcpy(total,nombre1);
        strcat(total,",");
        if (strcmp(nombre2,nombre3)<0)
        {
            strcat(total,nombre2);
            strcat(total,",");
            strcat(total,nombre3);
        }
        else
        {
            strcat(total,nombre3);
            strcat(total,",");
            strcat(total,nombre2);
        }
    }
    else
    {
        if (strcmp(nombre2,nombre3)<0)
        {
            strcpy(total,nombre2);
            strcat(total,",");
            if (strcmp(nombre1,nombre3)<0)
            {
                strcat(total,nombre1);
                strcat(total,",");
                strcat(total,nombre3);
            }
            else
            {
                strcat(total,nombre3);
                strcat(total,",");
                strcat(total,nombre1);
            }
        }
        else
        {
            strcpy(total,nombre3);
            strcat(total,",");
            if (strcmp(nombre1,nombre2)<0)
            {
                strcat(total,nombre1);
                strcat(total,",");
                strcat(total,nombre2);
            }
            else
            {
                strcat(total,nombre2);
                strcat(total,",");
                strcat(total,nombre1);
            }
        }
    }
    printf("Nombres ordenados alfabeticamente\n");
    printf("%s",total);
    getch();
    return 0;
}

Retornar