Fundamentos de Informática ETSID Tema 7 (II): Cadenas de caracteres. Departamento de Sistemas Informáticos y Computación Universidad Politécnica de Valencia Índice 1. 2. 3. 4. 5. Introducción. Inicialización de cadenas. Lectura de cadenas. Escritura de cadenas. Funciones de tratamiento de cadenas. 1 1. Introducción Cadena: vector unidimensional de caracteres formado por una o varias palabras que finaliza con un carácter especial denominado carácter de fin de cadena (‘\0’). Ejemplo: char v[100]; /* Puede contener 99 caracteres y \0 */ 2. Inicialización de cadenas char cadena1[ ] = “Hola caracola”; char cadena2[81] = “Hola caracola”; char cadena3[ ] = {‘H’, ‘o’, ‘l’, ‘a’, ‘ ’, ‘c’, ‘a’, ‘r’, ‘a’, ‘c’, ‘o’, ‘l’, ‘a’, ‘\0’}; cadena1 H o cadena2 H o cadena3 H o l l a a l c c a a c a r a r a c o a c o l r o a c l a a \0 l a \0 ... p.80 \0 2 3. Lectura de cadenas z fgets(), gets(): z z z z Lee una cadena de caracteres hasta que se pulsa intro. Se añade el carácter ‘\0’. Lee espacios en blanco. Lee palabras. fscanf(), scanf(): z z z Lee una cadena de caracteres hasta que encuentra un blanco, tabulador o intro. Se añade el carácter ‘\0’. No lee blancos. Lee frases. fgets() y gets() fgets(cadena, tamaño, fichero) Ö fichero gets(cadena) Ö teclado Ejemplo: char nombre[81]; gets(nombre); 3 fscanf() y scanf() fscanf() Ö fichero scanf() Ö teclado z Lectura de cadenas con formato. Carácter de control %s. Se leen datos hasta que encuentra un blanco, tabulado o nueva línea. Si se especifica una anchura de campo, recoge como máximo ese número de caracteres. Retorna el número de caracteres leídos. z Lectura de la cadena completa: z z z z z Carácter de control: %s. La variable tipo cadena no debe ir precedida de &. Lectura carácter a carácter (bucle): z z Carácter de control %c. La variable si debe ir precedida de &. Ejemplo: char cadena[81]; scanf(“%s”, cadena); scanf(“%c”, &cadena[7]); 4 Ejemplo char nombre1[40], nombre2[11]; scanf(“%s %10s”, nombre1, nombre2); printf(“He leído los nombres %s y %s\n”, nombre1, nombre2); Entrada: Jacinto y Juan Salida: Jacinto Juan Entrada: José y Papapopoulos Salida: z gets, fgets: cuando el texto leído tenga espacios en blanco. z z José y Papapopoul Ejemplos: nombre de una persona, nombre de una calle,... scanf, fscanf: cuando no haya blancos. z z Ejemplos: nombre de una pieza en un almacén. En general cuando queremos asegurar que no haya blancos. 5 Ejemplo: char nombre[100]; printf(“Introduce tu nombre y tus apellidos: “); gets(nombre); Õ Pepito Pérez P e p i t o 0 1 2 3 4 5 6 P é r e z \0 7 8 9 10 11 12 … 99 printf(“Introduce tu nombre y tus apellidos: “); scanf(“%s”,nombre); Õ Pepito Pérez P e p i t o \0 … 0 1 2 3 4 5 6 7 8 9 10 11 12 99 4. Escritura de cadenas printf() z Comando de control: %s. Ejemplo: #define mi_nombre “Pepito” char nombre1[81], nombre2[81] = “Juanito”; scanf(“%s”,nombre1); Õ “Jorgito” printf(“%s\n%s\n%s\n”, mi_nombre, nombre1, nombre2); Salida: Pepito Jorgito Juanito 6 5. Funciones de tratamiento de Cadenas z Incluidas en la librería: #include <string.h> z strcpy: copia o asignación de cadenas. strlen: longitud de una cadena. strcmp, strncmp: comparación de cadenas. strcat, strncat: concatenado de cadenas. strchr, strstr: búsqueda en cadenas. z z z z strcpy (cadena_destino, cadena_origen) En la copia se incluye el carácter ‘\0’. Ejemplo: char c1[20] = “Pepito ”; char c2[20] = “Juanito”; char aux[81]; strcpy (aux, c1); strcpy (c1, c2); strcpy (c2, aux); 7 long int strlen (cadena) z z Cuenta el número de caracteres de la cadena y retorna la longitud. El carácter ‘\0’ no se cuenta. Ejemplo: char nombre[ ]=“Pepito Pérez”; printf(“Longitud de %s: %d\n”, nombre, strlen(nombre)); Salida: Longitud de Pepito Pérez: 12 Ejemplo Leer el nombre de una persona y mostrar dicho nombre con un carácter en cada línea. 8 #include <stdio.h> #include <string.h> void main() { for (i=0; nombre[i]!=‘\0’; i++) int i; char nombre[81]; printf(“Dime tu nombre: “); gets(nombre); for (i=0; i<strlen(nombre); i++) printf(“%c\n”, nombre[i]); } int strcmp (cadena1, cadena2) Compara dos cadenas alfabéticamente y retorna: de caracteres Valor retornado Comparación <0 cadena1 < cadena2 0 cadena1 == cadena1 >0 cadena1 > cadena 2 9 Ejemplo Leer los nombres de 2 personas y mostrarlos ordenados alfabéticamente. #include <stdio.h> #include <string.h> void main() { int resultado; char nombre1[81], nombre2[81]; printf(“Dime los nombres: “); gets(nombre1); gets(nombre2); resultado = strcmp(nombre1, nombre2); if (resultado>=0) /* Iguales o mayor el primero*/ printf(“%s\n%s\n”,nombre1,nombre2); else /* Mayor el segundo */ printf(“%s\n%s\n”,nombre2,nombre1); } 10 int strncmp (cadena1, cadena2, n) Compara alfabéticamente los n primeros caracteres de dos cadenas y retorna: Valor retornado Comparación <0 n caracteres de cadena1 < n caracteres de cadena 2 0 n caracteres de cadena1 == n caracteres de cadena1 n caracteres de cadena1 > n caracteres de cadena 2 >0 strcat (cadena_destino, cadena_origen) Concatena dos cadenas de caracteres. 11 Ejemplo Leer el nombre y los dos apellidos de una persona y unirlo en una única cadena. #include <stdio.h> #include <string.h> void main() { char nombre[26], apellido1[26], apellido2[26],completo[81]; printf(“Dime el nombre y los apellidos: “); gets(nombre); gets(apellido1); gets(apellido2); strcpy(completo, nombre); strcat(completo, “ ”); strcat(completo,apellido1); strcat(completo, “ ”); strcat(completo,apellido2); } 12 strncat (cadena_destino, cadena_origen, n) Copia sólo los n primeros caracteres de la cadena origen en la cadena destino. char *strchr (cadena, carácter) z z z Busca la primera ocurrencia del carácter dentro de la cadena. Retorna la cadena a partir del carácter encontrado (incluido dicho carácter). Si no existe retorna el puntero nulo NULL. 13 Ejemplo Leer el nombre de una persona y un carácter y comprobar si dicho carácter está en su nombre. char nombre[81], caracter; printf(“Introduce el nombre: “); gets(nombre); printf (“Introduce el carácter a buscar\n”); scanf(“%c”,&carácter); if (strchr (nombre, caracter)!=NULL) printf (“La cadena encontrada a partir del carácter %c es %s\n”, caracter, strchr (nombre, caracter); else printf (“No se ha encontrado el carácter %c\n”, caracter); char *strrchr (cadena, carácter) La búsqueda se realiza desde el final de la cadena. char *strstr (cadena_búsqueda, cadena_buscada) Busca una cadena dentro de otra. 14 Ejemplo Leer el nombre de una persona y un apellido y comprobar si el apellido pertenece a esa persona. char nombre[81], apellido[26]; printf(“Introduce el nombre: “); gets(nombre); printf (“Introduce el apellido\n”); gets(apellido) if (strstr (nombre, apellido)!=NULL) printf (“El apellido está en el nombre”); else printf (“No se ha encontrado el apellido”); Ejercicio La función strlen(cadena) calcula la longitud de la cadena que se le pasa como parámetro. Crear una función llamada longitud que haga lo mismo. 15 #define N 81 int longitud (char v[N]) { int i=0; while (i<N && v[i]!=‘\0’) i++; return i; } void main() { char c[N]; printf(“Introduce un nombre: “); gets(c); printf(“La longitud de %s es %d\n”, c, longitud(c)); } Ejercicio La función strcat(c1, c2) concatena la cadena c2 al final de la cadena c1 (deja el resultado en c1 y c2 no se modifica). Crear una función llamada concatena que haga lo mismo. Utilizar la función longitud del ejercicio anterior. 16 #define N 81 void concatena (char c1[N], char c2[N]) { int i; i=longitud(c1); for (j=0; j<longitud(c2); j++) { c1[i]=c2[j]; i++; } c1[i]=‘\0’; } void main() { char c1[N], c2[N]; printf(“Introduce el primer nombre: “); gets(c1); printf(“Introduce el segundo nombre: “); gets(c2); concatena(c1, c2); printf(“Resultado: %s\n”, c1); } 17 Ejercicio Leer 3 cadenas de caracteres: z z z Una cadena que contenga el nombre de pila de un alumno de una clase. Una cadena que contenga el primer apellido. Una cadena que contenga el segundo apellido. Se pide, crear una cadena con el siguiente formato: apellido1 apellido2, inicial. #define TAM 81 void convierte (char a1[TAM], char a2[TAM], char nom[TAM], char res[TAM]) { int pos; strcpy(res, a1); strcat(res, “ ”); strcat(res, a2); strcat(res, “, ”); pos = strlen(res); res[pos]=nom[0]; res[pos+1] = ‘.’; res[pos+2] = ‘\0’; } 18 void main () { char a1[TAM], a2[TAM], nom[TAM], res[TAM]; printf(“Introduce el primer apellido: “); gets(a1); printf(“Introduce el segundo apellido: “); gets(a2); printf(“Introduce el nombre: “); gets(nom); convierte(a1, a2, nom, res) printf(“%s\n”,res); } Ejercicio Leer una cadena de caracteres, donde en lugar de ñ se han utilizado los caracteres ny. Crear una nueva cadena sustituyendo ny por ñ. de caracteres 19 #include <stdio.h> #define N 100 void quitar_ny (char c[]) { int i=0, j; /* Bucle que recorre todo el vector buscando ny. La búsqueda termina cuando llega al final de la cadena (\0). */ while (c[i]!='\0') { if (c[i]=='n' && c[i+1]=='y') { /* Sustituir ny por ñ */ c[i]='ñ'; /* Correr una posición cada carácter del resto del vector */ j=i+1; while (c[j]!='\0') { c[j]=c[j+1]; j++; } } i++; } } int main() { char cadena[N]; printf("Introduce una frase: "); gets(cadena); quitar_ny(cadena); printf("Resultado: %s\n", cadena); system("PAUSE"); return 0; } 20