Вы находитесь на странице: 1из 21

ARACTERES Y CADENAS EN C.

El tipo Carcter en C El tipo Cadena en C E/S de Caracteres y Cadenas - Problemas derivados del uso de un tampn Funciones de tratamiento de cadenas Ejercicios propuestos

El tipo Carcter en C El nombre del tipo carcter en C es char. Este tipo ocupa un byte (ocho bits) de extensin, y puede interpretarse con y sin signo. La tabla de tipos de datos de carcter en C es como sigue:

Nombre
char signed char unsigned char

Extensin Alcance 8 bits Cualquier cdigo ASCII 8 bits desde -128 hasta +127 8 bits desde 0 hasta 255

Vase a continuacin un ejemplo de utilizacin de variables de los tipos anteriores:


#include<stdio.h> char letra; signed char letraconsigno; unsigned char letrasinsigno; int main(int argc, char * argv[]) { letra = 'A'; printf("La letra es %c y su valor decimal es %d.\n\n", letra,letra); letraconsigno = -65; printf("Letraconsigno es %d y su valor decimal es %d.\n\n", letraconsigno,letraconsigno); letrasinsigno = 165; printf("Letrasinsigno es %u y su valor decimal es %d.\n\n", letrasinsigno,letrasinsigno); return 0; }

Y el resultado de ejecutar este programa es:


La letra es A y su valor decimal es 65. Letraconsigno es -65 y su valor decimal es -65. Letrasinsigno es 165 y su valor decimal es 165.

Como puede apreciarse, el descriptor empleado para la lectura y escritur de variables de tipo char es %c. Nota.- La lectura de caracteres individuales plantea una insospechada dificultad, debida a que C es literal, y cuando se le pide que lea un caracter, obedece sin rechistar. Pero no hemos pulsado un carcter, sino dos, verdad? Vase el siguiente Ejemplo
#include<stdio.h> /* Este programa muestra los peligros que acechan al incauto lector de caracteres */ char unaletra, otraletra; void main(void) { printf("Escriba una letra y pulse intro, por favor: "); scanf("%c", &unaletra); printf("La letra que ha pulsado era %c y su valor decimal es %d\n", unaletra, unaletra); printf("Ahora escriba otra letra, por favor: "); scanf("%c", &otraletra); printf("La letra que ha pulsado era %c y su valor decimal es %d\n", otraletra, otraletra); printf("\n\nTerminacin normal del programa.\n\n"); } /* El resultado de la ejecucin de este programa es: Escriba una letra y pulse intro, por favor: a La letra que ha pulsado era a y su valor decimal es 97 Ahora escriba otra letra, por favor: La letra que ha pulsado era y su valor decimal es 10 Terminacin normal del programa. Qu ha pasado? */

Existen varias posibilidades para descartar el carcter sobrante. Una de ellas es emplear un descriptor que ignora el carcter siguiente al ledo: %c%*c en lugar de %c. Tambin se puede recurrir a las funciones gets() y fgets(), que ofrece stdio.h, y que sirven para leer cadenas. La primera, gets() lee del teclado hasta que encuentra el retorno de carro; se retorno no se incluye en la cadena proporcionada y gets() podra servir muy bien para vaciar el bfer si no fuera peligrosa: es responsabilidad del usuario reservar espacio suficiente para la cadena leda. Dado que no es posible anticipar con seguridad lo que har el usuario, resulta ms prudente emplear fgets(). Esta funcin si permite determinar el nmero mximo de caracteres ledos, y devuelve un puntero nulo cuando el bfer est vaco. Una tercera solucin, finalmente, consiste en invocar a la funcin fpurge(stdin) inmediatamente despus de leer el carcter. De este modo se descarta directamente el contenido restante en el bfer de teclado. Slo hay un problema: es propia de Unix, y los entornos que no estn basados en este estndar suelen carecer de ella. El tipo Cadena en C Una cadena es una sucesin de caracteres, cuyo final est marcado mediante el carcter '\0', que se emplea como marcador de fin de cadena. Obsrvese que se ha encerrado la expresin \0 entre comillas sencillas y no dobles. Esto denota que se trata de un carcter; si se hubiera encerrado entre comillas dobles se tratara de la cadena formada por este carcter... y tendra dos bytes de longitud, siendo el ltimo, precisamente, '\0'. La adicin de este carcter de finalizacin es imprescindible, toda vez que ser empleado por todas las funciones de tratamiento de cadenas. Las cadenas de C se declaran como listas de caracteres. El carcter de terminacin tambin cuenta, y ocupa un byte igual que cualquier otro. Por tanto, una cadena para la cual se reserven 80 caracteres podr contener un mximo de 79 caracteres del usuario, ms el carcter de terminacin. Esto no implica, desde luego, que sea obligatorio emplear siempre todos los caracteres reservados... con el consiguiente desperdicio de espacio en la mayora de las ocasiones. La funcin strlen(),que pertenece a string.h, permite determinar el nmero exacto de caracteres de la cadena utilizados realmente. El operador sizeof() proporciona el nmero total de caracteres reservados para la cadena. Consltense las pginas man. Las cadenas se declaran mediante expresiones de la forma siguiente:
char cadena[numero_total_de_bytes_reservados]; o bien char cadena[] = "Algn valor"; o bien, incluso, char cadena[] = { 'U', 'n', 'o', 's', ' ', 'c', 'u', 'a', 'n', 't', 'o', 's', ' ', 'c', 'a', 'r', 'c', 't', 'e', 'r', 'e', 's', '\0'}; Obsrvese que el compilador reserva, en los dos ltimos casos, el

espacio necesario para almacenar la cadena deseada. El compilador, en el caso de dar valor inicial a la cadena, incluyen el marcador de fin de cadena '\0' an cuando ste no se indique explcitamente. No sucede lo

mismo cuando se omite el carcter '\0' en la ltima declaracin. Vase el siguiente ejemplo: #include<stdio.h> int main(int arcg, char* argv[]) {
char c1[8]; char c2[] = "Hola"; char c3[] = { 'U', 'n', 'o', 's', ' ', 'c', 'u', 'a', 'n', 't', 'o', 's', ' ', 'c', 'a', 'r', 'a', 'c', 't', 'e', 'r', 'e', 's', '\0'}; strcpy(c1,"hola"); printf("Esto es c1 %s\n", c1); printf("Esto es c2 %s\n", c2); printf("Esto es c3 %s\n", c3); return 0; } Obsrvese la necesidad de emplear la funcin strcpy() para dar valor a c1, que inicialmente no haba recibido valor alguno. El compilador no

admite el operador de asignacin como mtodo para dar valor a esta cadena, porque intentara interpretar esa expresin empleando la lgica de punteros. En efecto: intente cambiar la expresin strcpy(c1, "Hola") por c1 = "Hola" y compile el programa. Obsrvese tambin que aparecen caracteres adicionales al imprimir si se suprime el ltimo carcter (el'\0') al declarar c3. Esto se debe a que printf() sigue imprimiendo caracteres en pantalla hasta llegar (casualmente) a un byte de valor 0. E/S de Caracteres y Cadenas - Problemas derivados del uso de la memoria intermedia de teclado. Las cadenas pueden leerse y escribirse mediante el uso de scanf() y printf() respectivamente. Es preciso tener en cuenta que scanf() detiene la lectura de caracteres en cuanto encuentra un espacio en blanco o tabulador. Vase un ejemplo Ejemplo
#include<stdio.h> /* Este programa muestra la utilizacin de cadenas en C */ char cadena[8], resto[80]; void main(void) { printf("Escriba una cadena: "); scanf("%s", cadena); /* Las cadenas NO llevan & */ printf("\n\nLa cadena leda era %s\n\n", cadena); printf("Y el resto era"); gets(resto); puts(resto); printf("Terminacin normal del programa.\n\n");

} Es interesante recordar que todo lo que "sobra", esto es, lo que est ms all del primer espacio en blanco, queda almacenado y disponible para la

siguiente sentencia de lectura. La funcin gets() captura todo lo restante, y despus se imprime mediante puts(). Hay que ser precavidos a la hora de "dejar" restos en el tampn. Lo mejor es eliminar posibles restos antes de pasar a la lectura siguiente, empleandofflush(stdin) o bien fpurge(stdin). Funciones de tratamiento de cadenas El archivo de encabezado string.h contiene numerosas funciones relacionadas con el tratamiento de caracteres. Vase a continuacin una tabla de funciones tiles:
/* * */ Funciones de concatenacin

Encabezado
char *strcat (char *s1, const char *s2);

char *strncat (char *s1, const char *s2, size_t n); /* * */ Funciones de comparacin

Descripcin Esta funcin aade s2 a s1 y pone un '\0' al final del resultado; se supone que s1 contiene espacio suficiente para el total de caracteres (los de s1, los de s2 y el '\0'). Proporciona como resultado un puntero de s1 Anloga a la anterior, pero aade a s1 un mximo de n caracteres de s2. Proporciona como resultado un puntero de s1

Encabezado

int memcmp (const void *s1, const void *s2, size_t n);

Descripcin Compara byte por byte las dos cadenas cuya direccin se proporciona, suponiendo que ambas tuvieran n bytes de longitud. Si ambas series de bytes son iguales, la funcin proporciona el valor 0. Si no son iguales, la funcin devuelve la diferencia entre los dos primeros bytes distintos. La comparacin es numrica, sin tener en cuenta el orden alfabtico internacional, lo cual produce resultados extraos cuando las cadenas contienen signos diacrticos. Esta funcin compara byte por byte las cadenas de caracteres sealadas por s1 y s2. El resultado es:

int strcmp (const char *s1, const char *s2);

negativo si s1 es menor que s2 nulo si s1 y s2 son iguales positivo si s1 es mayor que s2

Esta funcin sirve para comparar dos cadenas, y hace uso de la secuencia int strcoll (const char *s1, const lexicogrfica (locale) definida en el char *s2); momento de su ejecucin. Produce valores numricos anlogos a los de strcmp() Esta funcin es una variante int strncmp (const char *s1, const de strcmp() que compara nicamente char *s2, size_t n); los n primeros caracteres de ambas cadenas. Almacena en s1 la traduccin de la cadena s2 a la configuracin de locale definida en el momento de la size_t strxfrm (char *s1, const char ejecucin. Esta funcin puede no estar *s2, size_t n); presente en todas las implementaciones de la biblioteca de C; consltense las pginas man de la mquina utilizada.
/* * */ Funciones de bsqueda

Descripcin Determina la posicin de la primera aparicin de c(que se interpreta como carcter sin signo) dentro de los n primeros void *memchr (const void *s, int c, bytes de la cadena s. Si c forma parte de s, size_t n); se proporciona como resultado un puntero de c. Si c no forma parte de s, se proporciona el puntero nulo. Anloga a la anterior, salvo que se explora toda la cadena, incluyendo el marcador char *strchr (const char *s, int c); final '\0'. Por tanto, si se busca '\0', se encontrar el marcador de fin de cadena. Esta funcin calcula la longitud del segmento mximo de s1 que est formado por size_t strcspn (const char *s1, caracteres queno estn presentes en s2. const char *s2); Dicho en pocas palabras, sirve para calcular la longitud de la subcadena complementaria. Esta funcin busca en s1 la primera aparicin de cualquier carcter de los contenidos en s2 y proporciona su direccin char * strpbrk (const char *s1, const char *s2); (mediante un puntero de carcter). Si s1 no contiene ningn carcter de s2, se proporciona el puntero nulo. Esta funcin busca un carcter c dentro de la char *strrchr (const char *s, int cadenas, empezando por el final. Si lo c); encuentra, proporciona su direccin mediante

Encabezado

un puntero. Si no lo encuentra, proporciona el puntero nulo. Dicho de otro modo, strrchr() busca la ltima aparicin de cen s. Esta funcin calcula la longitud del mximo size_t strspn (const char *s1, const segmento inicial de s1 que est formado char *s2); completamente por caracteres presentes en s2. Esta funcin busca la primera aparicin de s2 dentro de s1, sin tener en cuenta el carcter de fin de cadena. Si s2 se encuentra char *strstr (const char *s1, const en s1, la funcin proporciona un un puntero char *s2); del primer byte de s2dentro de s1. Si no se encuentra s2 dentro de s1, se proporciona el puntero nulo. Esta funcin extrae subcadenas (tokens) de s1. Los separadores de subcadenas son los caracteres que contenga s2. La primera subcadena se proporciona (mediante un puntero) cuando se llama a strtok()empleando s1 y s2 como parmetros. La segunda subcadena (y siguientes) se obtienen mediante llamadas a strtok() con el puntero nulo como primer argumento, y con la cadena de separadores char *strtok (char *s1, const char como segundo argumento (sta se puede *s2); modificar en las distintas llamadas). Cuando ya no quedan ms subcadenas, la funcin proporciona el puntero nulo. Obsrvese la notable utilidad de esta funcin para la lectura de archivos de texto con formato delimitado. Obsrvese tambin que, una vez invocada la cadena por primera vez, se admiten cambios en el delimitador especificado (que es una cadena! Se pueden emplear delimitadores "complejos", formados por mltiples caracteres.)
/* * */ Varios

Descripcin Sirve para rellenar la cadena sealada por s, void *memset (void *s, int c, size_t copiando en sus bytes el valor de c, n); interpretado como carcter sin signo. Se escribe un mximo de nbytes.

Encabezado

char *strerror (int errnum);

size_t strlen (const char *s);

Esta funcin recibe como argumento un nmero de error y proporciona como resultado el mensaje de error correspondiente. Los nmeros y mensajes de error dependen por completo del compilador (y de la plataforma). Proporciona la longitud de la cadena sealada por s.

Un ejemplo Construir un programa que muestre la forma de utilizar las principales funciones de tratamiento de cadenas en C. El programa debe mostrar procedimientos de lectura, escritura, comparacin, concatenacin y bsqueda de fragmentos.
/* * funciones.h * cadenas * * Created by coti on 28/08/09. * Copyright 2009 Tests by Coti. All rights reserved. * */ #include <stdio.h> /* aqu vive strlen() */ #include <string.h>

funciones.h /* CONSTANTES */
#define NUM_BYTES 128 #define LONGITUD_1 64 #define LONGITUD_2 64 void void void void void void /* * * * * * * leer(char * p1, char * p2); mostrar(char * p1, char * p2); recorrer(char * p1, char * p2); comparar(char * p1, char * p2); concatenar(char * p1, char * p2, char * pc); buscar(char * p1, char * p2, char * pc); funciones.c cadenas Created by coti on 28/08/09. Copyright 2009 Tests by Coti. All rights reserved.

funciones.c

*/ #include "funciones.h" void leer(char * p1, char * p2) { printf("\nEscriba la primera palabra: "); fgets(p1, LONGITUD_1, stdin); p1[strlen(p1)-1] = '\0'; printf("\nEscriba la segunda palabra: "); fgets(p2, LONGITUD_2, stdin); p2[strlen(p2)-1] = '\0'; printf("\n"); } void mostrar(char * p1, char * p2) { printf("\nLa primera palabra es %s y la segunda es %s\n\n", p1, p2); } void recorrer(char * p1, char * p2) { int i; printf("\nLos caracteres de la palabra %s son:\n\n",p1); for (i=0; i<strlen(p1); i++) { printf("%3d %c\n", (unsigned char)p1[i], p1[i]); } printf("\nLos caracteres de la palabra %s son:\n\n",p2); for (i=0; i<strlen(p2); i++) { printf("%3d %c\n", (unsigned char)p2[i], p2[i]); } printf("\n"); } void comparar(char * p1, char * p2) { int resultado = strcmp(p1, p2); /* convertimos el resultado en un valor q es 1, 0 o -1 */ resultado = resultado > 0 ? 1 : (resultado < 0 ? -1 : 0); switch (resultado) { case -1: printf("\n%s es menor que %s\n",p1,p2); break; case 0: printf("\n%s es igual que %s\n",p1,p2); break; case 1: printf("\n%s es mayor que %s\n",p1,p2); break; default: break; }

printf("\n"); } void concatenar(char * p1, char * p2, char * pc) { strcpy(pc, ""); strcat(pc, p1); strcat(pc, " "); strcat(pc, p2); printf("\nLa concatenacin de %s y %s es %s\n\n",p1, p2, pc); } void buscar(char * p1, char * p2, char * pc) { char * resultado = NULL; printf("\nEscriba la palabra que busca: "); fgets(pc, NUM_BYTES, stdin); pc[strlen(pc)-1] = '\0'; resultado = strstr(p1, pc); if (NULL == resultado) printf("\n%s no contiene a %s\n",p1,pc); else { printf("\n%s contiene a %s\n",p1,pc); } resultado = strstr(p2, pc); if (NULL == resultado) printf("\n%s no contiene a %s\n",p2,pc); else { printf("\n%s contiene a %s\n",p2,pc); } printf("\n"); } #include <stdio.h> /* malloc() vive aqu */ #include <stdlib.h> /* toupper() vive aqu */ #include <ctype.h> /* Las funciones viven aqu */ #include "funciones.h" /* Este programa muestra ejemplos de las operaciones fundamentales con cadenas:

main.c

*/

declaracin (esttica) lectura escritura recorrido comparacin concatenacin bsqueda de fragmentos

int main (int argc, const char * argv[]) { /* Las variables palabra_1 y palabra_2 son cadenas de

LONGITUD_1 y LONGITUD_2 bytes respectivamente, y se declaran estticamente. */ char palabra_1[LONGITUD_1], palabra_2[LONGITUD_2]; /* La variable pcadena seala un bloque de memoria de dimensiones iguales a la suma de dimensiones de palabra_1 y palabra_2. */ char * pcadena = malloc((LONGITUD_1+LONGITUD_2)*sizeof(char)); /* Este es el men q muestra la aplicacin */ char menu[] = "1)Leer 2)Mostrar 3)Recorrer 4)Comparar\n5)Concatenar 6)Buscar fragmento Q) Salir"; /* Esta es la opcin q escribe el usuario */ char opcion; /* Esta es la condicin de finalizacin del programa */ int terminar = 0; do { printf("%s ", menu); scanf("%c%*c",&opcion); opcion = toupper(opcion); switch (opcion) { case '1': printf("\nLectura de cadenas\n"); leer(palabra_1, palabra_2); break; case '2': printf("\nEscritura de cadenas\n"); mostrar(palabra_1, palabra_2); break; case '3': printf("\nRecorrido de cadenas\n"); recorrer(palabra_1, palabra_2); break; case '4': printf("\nComparacin de cadenas\n"); comparar(palabra_1, palabra_2); break; case '5': printf("\nConcatenacin de cadenas\n"); concatenar(palabra_1, palabra_2, pcadena); break;

case '6': printf("\nBuscar un fragmento\n"); buscar(palabra_1, palabra_2, pcadena); break; case 'Q': printf("\nTerminacin del programa\n"); terminar = 1; break; default: break; } } while (!terminar); return 0; }

Comentarios Este programa consta de dos archivos, y se puede compilar desde la lnea de rdenes, o empleando cualquier IDE. Vanse las pginas
man

correspondientes a las distintas funciones. La arquitectura de programa es muy bsica; si se aade una funcin ms ser preciso modificar el programa principal. Sera posible emplear otra arquitectura menos engorrosa? Ejercicios resueltos y propuestos

1. Ejercicio 0103r01.-Un programa recibe un nombre y un apellido a travs del teclado, en la forma:
Por favor, dgame el nombre : Jos Por favor, dgame el apellido : Garca

Se pide construir y mostrar en pantalla una cadena de la forma:


Titular: Jos Garca.

Emplear las funciones de concatenacin descritas. Qu ocurre si la cadena formada es ms larga que la cadena de nombre?
2.

3. Ejercicio 0103r02.-Repetir el ejercicio anterior impidiendo la formacin de cadenas excesivamente largas. Si es necesario, se truncar la cadena y se avisar al usuario.
4. #include<stdio.h> 5.

6. #define DIM_NOMBRE 12 7. #define DIM_APELLIDOS 10 8. 9. int main(int argc, char *argv[]) 10. { 11. char nombre[DIM_NOMBRE], apellido[DIM_APELLIDOS]; 12. printf("\n\nPor favor, dgame el nombre : "); 13. fgets(nombre,sizeof(nombre),stdin); 14. /* fgets() retiene el retorno de carro, lo descartamos */ 15. nombre[strlen(nombre)-1] = '\0'; 16. /* Descartamos el resto si lo hay */ 17. fpurge(stdin); 18. printf("\n\nPor favor,dgame el apellido : "); 19. fgets(apellido,sizeof(apellido), stdin); 20. /* fgets() retiene el retorno de carro, lo descartamos */ 21. apellido[strlen(apellido)-1] = '\0'; 22. /* Si cabe en nombre el nombre, un espacio y el apellido, lo almacenamos */ 23. if (strlen(nombre) + strlen(" ") + strlen(apellido) < sizeof(nombre) -1) 24. { 25. strcat(nombre, " "); 26. strcat(nombre, apellido); 27. } 28. else /* Si no cabe, intentamos aadir el blanco y lo que quepa de apellido. 29. Hay que tener en cuenta que en nombre sobran slamente 30. sizeof(nombre) strlen(nombre) - 1 31. caracteres. Por tanto, limitamos a ste nmero 32. los caracteres aadidos (mediante strncat). 33. */ 34. { 35. strncat(nombre, " ", sizeof(nombre) - strlen(nombre)-1); 36. strncat(nombre, apellido, sizeof(nombre) - strlen(nombre)-1); 37. printf("Resultado demasiado largo, se ha truncado a %d caracteres.\n", 38. sizeof(nombre)-1); 39. }; 40. printf("\n\nTitular: %s\n", nombre); 41. printf("\n\nFin del programa.\n\n"); 42. return 0; 43. }

44. Ejercicio 0103r03.-Construir un programa que muestre mediante strerror() los mensajes asociados a diferentes cdigos de error.
45. #include<stdio.h> 46. 47. int main(int argc, char * argv[])

48. 49. 50. 51. 52. 53. }

{ int i; char * p; for(i=0;i<sys_nerr;i++) printf("%d.-%s\n", i, p); return 0;

Este programa producir resultados distintos en diferentes plataformas; adems, cada una de ellas proporciona un nmero diferente (sys_nerr) de mensajes de error. 54. Ejercicio 0103r04.-Construir un programa que admita dos cadenas, las compare e indique su relacin de orden: la primera es menor que la segunda, son iguales o la primera es mayor que la segunda (strcmp()).
55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. descartamos */ 68. 69. 70. 71. 72. "); 73. 74. descartamos */ 75. 76. 77. 78. 79. 80. 81. segunda); 82. 83. 84. 85. else if (relacion < 0) printf("%s es menor que %s\n", primera, segunda); else segunda[strlen(segunda)-1] = '\0'; relacion = strcmp(primera, segunda); printf("\n\nRelacin: "); if (relacion > 0) printf("%s es mayor que %s\n",primera, fgets(segunda,sizeof(segunda), stdin); /* fgets() retiene el retorno de carro, lo primera[strlen(primera)-1] = '\0'; /* Descartamos el resto si lo hay */ fpurge(stdin); printf("\n\nPor favor,escriba la segunda cadena : #include<stdio.h> #define DIM_primera 10 #define DIM_segunda 15 int main(int argc, char *argv[]) { char primera[DIM_primera], segunda[DIM_segunda]; int relacion, relacion2; printf("\n\nPor favor, escriba la primera cadena : "); fgets(primera,sizeof(primera),stdin); /* fgets() retiene el retorno de carro, lo

86.

printf("%s es igual a %s\n", primera, segunda); 87. /* 88. Pero probemos lo que sucede 89. si slo se comparan 6 caracteres 90. */ 91. relacion2 = strncmp(primera, segunda, 6); 92. 93. printf("\n\nRelacin2: "); 94. if (relacion2 > 0) 95. printf("%s es mayor que %s\n",primera, segunda); 96. else 97. if (relacion2 < 0) 98. printf("%s es menor que %s\n", primera, segunda); 99. else 100. printf("%s es igual a %s\n", primera, segunda); 101. printf("\n\nFin del programa\n\n"); 102. return 0; 103. } 104. 105. /* 106. El resultado de la ejecucin es como sigue: 107. 108. Por favor, escriba la primera cadena : abcdefppp 109. 110. 111. Por favor,escriba la segunda cadena : abcdefzzz 112. 113. 114. Relacin: abcdefpp es menor que abcdefzzz 115. 116. 117. Relacin2: abcdefpp es igual a abcdefzzz 118. 119. */

Como puede observarse en el resultado de la ejecucin, la funcin strncmp() permite limitar la comparacin al principio de las cadenas, produciendo resultados aparentemente falsos, aunque realmente sean exactos. 120. Ejercicio 0103r05.-Se dispone de una lista de nombres y apellidos. Se pide construir un programa que procese la lista y muestre todos los registros que contengan una cierta palabra, bien sea como nombre, como primer apellido o como segundo apellido (strstr()).
121. 122. 123. 124. 125. #include<stdio.h> #define FILAS 5 #define LONGITUD_CADENA 20 int main(int argc, char * argv[])

126. { 127. char nombre[FILAS][LONGITUD_CADENA] = { "Juan", "Martn", "Pedro", "Luis", "Alonso"}; 128. char apellido_1[FILAS][LONGITUD_CADENA] = {"Martin", "Perez", "Garcia", "Hernandez", "Lopez"}; 129. char apellido_2[FILAS][LONGITUD_CADENA] = {"Alonso", "Gonzalez", "Martin", "Luis", "Gomez"}; 130. char palabra[LONGITUD_CADENA]; 131. int i; 132. printf("\n\nBsqueda de registros\n\n"); 133. printf("La lista de registros es:\n\n"); 134. for(i=0;i<FILAS;i++) 135. printf("%d: %s %s %s\n", 136. i, 137. nombre[i], 138. apellido_1[i], 139. apellido_2[i]); 140. printf("\n\nEscriba una palabra: "); 141. scanf("%s", palabra); 142. printf("\n\nPalabra buscada: %s\n\n", palabra); 143. for(i=0;i<FILAS;i++) 144. { 145. if( strstr(palabra,nombre[i])!=NULL || 146. strstr(palabra,apellido_1[i])!=NULL || 147. strstr(palabra,apellido_2[i])!=NULL) 148. printf("%s figura en el registro %d: %s %s %s\n", 149. palabra, 150. i, 151. nombre[i], 152. apellido_1[i], 153. apellido_2[i]); 154. } 155. printf("\n\nFin del programa\n\n"); 156. return 0; 157. }

158. Ejercicio 0103r06.-Se dispone de una lista de registros de formato delimitado, esto es, cuyos campos estn separados por un carcter que no puede formar parte del campo. Se pide construir una funcin que admita esos registros y los separe en campos, mostrando esos campos en pantalla una vez separados (strtok()).
159. #include<stdio.h> 160. 161. #define FILAS 5 162. #define COLUMNAS 40 163. int main(int argc, char * argv[]) 164. { 165. char registro[FILAS][COLUMNAS] = { "Ana*Perez*Lopez", 166. 167. 168. 169.

"Bernardo*Ga "Carlos*Mart "Damian*Garc "Elena*Gonza

170. int i; 171. char * p; 172. for(i=0;i<FILAS;i++) 173. { 174. printf("\n\nLos campos del registro %s son:\n\n", registro[i]); 175. puts(strtok(registro[i], "*")); 176. while (p = strtok(NULL,"*")) 177. puts(p); 178. } 179. printf("\n\nFin del programa\n\n"); 180. return 0; 181. } 182.

El resultado de ejecutar este programa es precisamente el deseado:


/* Los campos del registro Ana*Perez*Lopez son: Ana Perez Lopez Los campos del registro Bernardo*Garcia*Gonzalez son: Bernardo Garcia Gonzalez Los campos del registro Carlos*Martin*Martin son: Carlos Martin Martin Los campos del registro Damian*Garcia*Perez son: Damian Garcia Perez Los campos del registro Elena*Gonzalez*Martin son: Elena Gonzalez Martin Fin del programa */

include <conio.h> #include <stdio.h> #include <string.h> main() { char dia[10]; int d; printf("Escribe un dia: "); gets(dia); if(strcmp(dia,"lunes")==0) { puts(dia);printf("es habil");} else if (strcmp(dia,"martes")==0) {puts(dia);printf("es habil");} else if (strcmp(dia,"miercoles")==0) {puts(dia);printf("es habil");} else if (strcmp(dia,"jueves")==0) {puts(dia);printf("es habil");} else if (strcmp(dia,"viernes")==0) {puts(dia);printf("es habil");} else if (strcmp(dia,"sabado")==0) {puts(dia);printf("es Fin de Semana");} else if(strcmp(dia,"domingo")==0) {puts(dia);printf("es Fin de Semana");} else printf("Error..."); getch(); }

Comparacin de dos strings usando funcin strcmp() */ #include <stdio.h> int main() { char nombre1[20], nombre2[20]; printf(''De el primer nombre:''); scanf(''%s'',nombre1); printf(''De el segundo nombre:''); scanf(''%s'',nombre2); n = strcmp(nombre1, nombre2); if (n == 0)

printf(''Nombres iguales \n''); else if (n > 0) printf(''Primer nombre mas grande que el segundo \n''); else printf(''Primer nombre mas chico que el segundo \n''); }
Como comparo 2 cadenas de caracteres sin morir en el intento? [ 6105 ] Supongamos que deseamos comparar el contenido de 2 cadenas o arreglos de caractres definidos como: Cdigo:

char nombre1[15]; char nombre2[15];


La mayora de personas usa formas incorrectas y que pueden llegar a colgar el programa de forma inesperada ou obtener resultados incorrectos: Cdigo:

if(nombre1==nombre2)...
Lo correcto cuando se trata de comparar 2 cadenas es usar la funcin strcmp de la biblioteca string.h de la siguiente forma: Cdigo:

if(!strcmp(nombre1,nombre2)) { /* nombre 1 y nombre2 son iguales */ } else { /* nombre 1 y nombre2 son distintos */ }
Como convertir una cadena a int? [ 6251 ] Para convertir una cadena a un entero lo ms fcil es usar la funcin atoi definida en stdlib.h por ejemplo: Cdigo:

char *cadena = "4856"; int num = atoi(cadena);


Pero si no queremos dicha funcin podemos construir nuestra propia funcin, para tener algo como: Cdigo:

char *cadena = "4856"; int num = convertir_entero(cadena);


Usamos la funcin convertir_entero, cuyo cdigo es el siguiente:

Cdigo:

int longitud(char *cadena) { int valor = 0; int i; for(i=0; cadena[ i ]!='\0'; i++) valor++; return valor; } int convertir_entero(char *cadena) { int potencias[5]={1,10,100,1000,10000}; int i; int valor = 0; int lon = longitud(cadena); for(i=lon-1; i>=0; i--) valor += (cadena[ i ]-'0') * potencias[ lon-i-1 ]; return valor;
Hallar el nmero de repeticiones de los elementos en un arreglo [ 2322 ]

Cdigo:

#define MAX 10 typedef int TaNumeros[MAX];


La siguiente funcin muestra el nmero de repeticiones de cada uno de los elementos del arreglo: Cdigo:

void Mostrar(TaNumeros aNumeros, int eTotal) { TaNumeros aCopia, aRep; int i, j, k, eElementos; /* Saca copia del arreglo */ for(i=0;i < eTotal; i++) aCopia[ i ]=aNumeros[ i ]; /* Saca numeros distintos */ eElementos = eTotal; for(i=0;i < eElementos;i++) { for(j=i+1; j < eElementos;j++) { /* Si encuentra numero repetido */ if(aCopia[ i ]==aCopia[ j ]) { /* Recorre una posicion elementos posteriores */ for(k=j+1;k < eElementos;k++) aCopia[k-1]=aCopia[k]; eElementos--; j--; } } }

/* Halla repeticiones de cada numero distinto */ for(i=0; i < eElementos; i++) aRep[ i ] = 0; for(i=0; i < eElementos; i++) for(j=0;j < eTotal;j++) if(aCopia[ i ]==aNumeros[j]) aRep[ i ]++; /* Imprime elementos del arreglo original */ printf("\n\nArreglo original: "); for(i=0; i < eTotal; i++) { printf("%d ", aNumeros[ i ]); } /* Imprime numeros y las veces que aparece */ printf("\n\nElemento -> Apariciones"); for(i=0; i < eElementos; i++) { printf("\n%d -> %d", aCopia[ i ], aRep[ i ]); } getch(); }

Вам также может понравиться