Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: dato000 en 13 Mayo 2015, 03:37 am



Título: [SOLUCIONADO] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: dato000 en 13 Mayo 2015, 03:37 am
Buenas, hacia tiempo no venia por aqui, cosas de la vida

Gente, por favor, necesito su ayuda, estoy atorado con este punto, pensaba que iba a funcionar, y me tiene extrañado el porque no funciona, si en mi prueba de escritorio deberia servir bien, es más tal vez un problema de abstracción lógica que de programación en si.

Verán, tengo que realizar una busqueda de un nombre de una persona, en un arreglo de 10 estructuras he guardado esa información de cada persona (nombre, edad), de forma tal que se tiene una estructura rapida de cada persona para buscar ya sea por nombre o por edad de persona.

Ahora, cuando estoy intentando buscar por el nombre de la persona, funciona, encuentra a la persona en ese arreglo, todo va bien, hasta el momento de imprimir en pantalla, pues solo me imprime siempre la primera posición del arreglo.

Esta es la parte en cuestión:

Código
  1. typedef struct persona
  2. {
  3.    char nombre[50];
  4.    int edad;
  5. } PERSONA;
  6.  
  7. int main()
  8. {
  9.    int i;
  10.    int posicionBusqueda=0;
  11.    char opcion;
  12.    char nombreBusqueda[50];
  13.    PERSONA arregloPersonas[10] = {  { "manu chao", 50},
  14.                                     { "maradona", 64},
  15.                                     { "pele", 79},
  16.                                     { "Tyrion", 34},
  17.                                     { "Lady", 26},
  18.                                     { "Lorena", 20},
  19.                                     { "Manuela", 15},
  20.                                     { "Jacobo", 7},
  21.                                     { "Salome", 3},
  22.                                     { "Camilo", 27}  };
  23.  
  24.    printf("\nNombre:  %s", arregloPersonas[9].nombre);
  25.    printf("\nEdad:  %i", arregloPersonas[9].edad);
  26.  
  27.    printf("HISTORIAL DE PERSONAS\n\n");
  28.    printf("a. Buscar por nombre\n");
  29.    printf("b. Buscar por edad\n");
  30.    printf("c. Salir\n\n");
  31.  
  32.    printf("Digite una opcion:  "); scanf("%c", &opcion);
  33.  
  34.    if(opcion == 'a' || opcion == 'A')
  35.    {
  36.        printf("Escriba el nombre de la persona que busca:  "),
  37.        scanf("%s", nombreBusqueda);
  38.        printf("Buscando...");
  39.        //sleep(2);
  40.        for(i=0; i<10; i++)
  41.        {
  42.            //if(nombreBusqueda == arregloPersonas[i].nombre)
  43.            if(strcmp(nombreBusqueda, arregloPersonas[i].nombre))
  44.            {
  45.                posicionBusqueda=i;
  46.                printf("\n\n\nNOMBRE ENCONTRADO!!\n");
  47.                printf("\n--Informacion de la Persona--");
  48.                printf("\nNombre de la Persona Buscada:  %s", arregloPersonas[i].nombre);
  49.                printf("\nEdad de la Persona Buscada:  %i", arregloPersonas[i].edad);
  50.                break;
  51.            }
  52.            else
  53.            {
  54.                printf("\n\nNOMBRE NO SE ENCUENTRA EN LA BASE DE DATOS.");
  55.                printf("\nIntente nuevamente.");
  56.                break;
  57.            }
  58.  
  59.            //posicionBusqueda++;
  60.        }
  61.  
  62.    }
  63.  
  64. ...
  65.  

Particularmente esta área, no se porque siempre me imprime la primera posición del arreglo de estructuras de las personas

Código
  1. for(i=0; i<10; i++)
  2.        {
  3.            //if(nombreBusqueda == arregloPersonas[i].nombre)
  4.            if(strcmp(nombreBusqueda, arregloPersonas[i].nombre))
  5.            {
  6.                posicionBusqueda=i;
  7.                printf("\n\n\nNOMBRE ENCONTRADO!!\n");
  8.                printf("\n--Informacion de la Persona--");
  9.                printf("\nNombre de la Persona Buscada:  %s", arregloPersonas[i].nombre);
  10.                printf("\nEdad de la Persona Buscada:  %i", arregloPersonas[i].edad);
  11.                break;
  12.            }
  13.            else
  14.            {
  15.                printf("\n\nNOMBRE NO SE ENCUENTRA EN LA BASE DE DATOS.");
  16.                printf("\nIntente nuevamente.");
  17.                break;
  18.            }
  19.  
  20.            //posicionBusqueda++;
  21.        }
  22.  


En verdad apreciaria cualquier aporte, me quede atorado y sigo investigando como remediar eso, pero realmente me dejo atonito que simplemente no funcionara siendo algo tan simple pero como  :huh: :huh: :huh:


Título: Re: [AYUDA] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: do-while en 13 Mayo 2015, 04:21 am
¡Buenas!

El fallo está aquí:
Código
  1. if(strcmp(nombreBusqueda, arregloPersonas[i].nombre))
  2.  

strcmp te devuelve el "orden alfabético" del primer argumento con respecto al segundo. Si el primero es alfabéticamente menor te devolverá un valor negativo, si es mayor positivo y si son iguales te devolverá cero. Tienes que poner un operador de negación ! antes de strcmp para que la condición sea cierta solo si la función te devuelve una condición falsa (0).

¡Saludos!


Título: Re: [AYUDA] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: dato000 en 13 Mayo 2015, 04:30 am
mmm no no es eso, ya lo habia intentado, verás, necesito que se cumpla la condición, si cambio la condición también tendria que cambiar el orden del if-else, y quedaria exactamente igual, porque si utilizo el operador ! lo que me indica para este caso es que lo encuentra pero no lo reporta.

Hasta hace unos minutos me di cuenta que si quito el break de la condición principal, imprime todo los datos Hasta la posición en la que encuentra el valor, que efectivamente, deberia imprimir.

Código
  1. if(strcmp(arregloPersonas[i].nombre, nombreBusqueda))
  2.            {
  3.  
  4.                printf("\n\n\nNOMBRE ENCONTRADO!!\n");
  5.                printf("\n--Informacion de la Persona--");
  6.                printf("\nNombre de la Persona Buscada:  %s", arregloPersonas[i].nombre);
  7.                printf("\nEdad de la Persona Buscada:  %i", arregloPersonas[i].edad);
  8.                //break;
  9.            }
  10.            else
  11.            {
  12.                printf("\n\nNOMBRE NO SE ENCUENTRA EN LA BASE DE DATOS.");
  13.                printf("\nIntente nuevamente.");
  14.                break;
  15.            }
  16.  

Por ese lado funciona, pero no me imprime la posición que busco (y es solo esa posición del arreglo de struct que necesito) mmmmmmm me quede corto con algo tan básico pero que pues, uds entienden, estanca.

Esto es lo que obtengo, por poner un ejemplo:

(http://i57.tinypic.com/20ky6c.png)


--------------------------------------------------------EDITADO--------------------------------------------

He notado una cosa, al editar la siguiente linea:

Código
  1. if(strcmp(arregloPersonas[i].nombre, nombreBusqueda) == 0)

Ahora todo da falso, claro, yo pensaba que podria utilizarse como un true/false, pero no habia visto que podia tomar 3 valores, en efecto, no se comportaba como esperaba, pero ahora menos, será por la naturaleza de las lineas de texto?? porque no son recibidas de la misma manera en las variables al ejecutar la comparación??


Título: Re: [AYUDA] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: rir3760 en 13 Mayo 2015, 05:56 am
no se porque siempre me imprime la primera posición del arreglo de estructuras de las personas
Porque:

* La función strcmp retorna un valor diferente de cero si las cadenas son distintas, solo retornara cero si son iguales.

+

* El bucle donde se realiza la búsqueda solo se ejecutara una vez ya que en ambas ramas de la sentencia condicional if terminas el bucle con la sentencia "break":
Código
  1. for (i = 0; i < 10; i++) {
  2.   if (strcmp (nombreBusqueda, arregloPersonas[i].nombre)) {
  3.      /* ... */
  4.  
  5.      break; /* Terminar el bucle si se cumple la condicion del if ... */
  6.   }else {
  7.      /* ... */
  8.  
  9.      break; /* ... y si no se cumple ... tambien */
  10.   }
  11.  
  12.   //posicionBusqueda++;
  13. }

+

* En la primera iteración del bucle se compara la palabra introducida por el usuario y leída con:
Código
  1. printf ("Escriba el nombre de la persona que busca:  "), /* mejor ';' */
  2. scanf ("%s", nombreBusqueda);
Con el campo "nombre" del primer elemento del array el cual consiste de dos palabras:
Código
  1. PERSONA arregloPersonas[10] = {  { "manu chao", 50}, /* ... */
En buen cristiano no hay forma de que la palabra introducida por el usuario sea igual a esas dos palabras.

Para solucionarlo debes leer la entrada del usuario con fgets (asegurate de eliminar el resto de la linea anterior) y utilizar un bucle sin cuerpo mas o menos así:
Código
  1. for (i = 0; i < 10 && strcmp(nombreBusqueda, arregloPersonas[i].nombre); i++)
  2.   ;
  3. if (i != 10 /* Hay que evitar magic numbers, mejor una macro*/)
  4.   puts("Nombre encontrado!");
  5. else
  6.   puts("El nombre no se encuentra en la base de datos");

Un saludo


Título: Re: [AYUDA] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: dato000 en 13 Mayo 2015, 18:42 pm
Pues francamente no ha funcionado, ya habia pensado lo del string con espacio, y lo habia arreglado, pero sigue igual, el break debo usarlo, porque sino me imprime todas las posiciones del arreglo, por lo que por ende, solo deberia romperse el ciclo for cuando realiza una comparacion exitosa, pero no es así, esto esta raro, pero siempre pasa con estos strings y caracteres en particular con C.

Ahora, lo más extraño es que fgets no quiere funcionar, se que es absurdo usar gets, pero fgets no quiere realizar lo que debe, no trabaja ningún caso, y ya probe diferentes cosas. También probe fflush(stdin) para limpiar el buffer de memoria al suponer que se produce un desbordamiento por el salto de linea en la lectura de la primera opción. Pero sigue igual  >:D >:D >:D.

 >:( >:( >:( >:( >:( >:( >:( >:( >:(

rir3760, te agradezco lo que mencionas de verdad que si, pero necesito imprimir en pantalla los datos del struct (nombre, edad) dependiendo de la busqueda, no es suficiente indicar con que se encuentra dentro del arreglo, porque no es lo que solicitaron.

Meh al final yo creo que lo voy a hacer en c++ para ver si ya no hay inconvenientes.


Título: Re: [AYUDA] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: Blaster en 13 Mayo 2015, 19:33 pm
rir3760, te agradezco lo que mencionas de verdad que si, pero necesito imprimir en pantalla los datos del struct (nombre, edad) dependiendo de la busqueda, no es suficiente indicar con que se encuentra dentro del arreglo, porque no es lo que solicitaron.

Solo es cuestión de agregarle algunos printf y ya

Código
  1. for (i = 0; i < 10 && strcmp(nombreBusqueda, arregloPersonas[i].nombre); i++);
  2.        if (i != 10)
  3.        {
  4.            printf("\n\n\nNOMBRE ENCONTRADO!!\n");
  5.            printf("\n--Informacion de la Persona--");
  6.            printf("\nNombre de la Persona Buscada:  %s", arregloPersonas[i].nombre);
  7.            printf("\nEdad de la Persona Buscada:  %i", arregloPersonas[i].edad);
  8.        }
  9.        else
  10.            puts("El nombre no se encuentra en la base de datos");
  11.  

Y del porque no funciona tu programa, ya te lo explicaron los compañeros mas arriba

Saludos


Título: Re: [SOLUCIONADO] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: dato000 en 13 Mayo 2015, 19:38 pm
No funciona así, como ya dije arriba también, pero te agradezco la intención.

realmente prefiero usar printf y scanf a gets y puts, cuestión de gustos.

Igual gente ya tengo la solución, al menos funciona para este simple ejercicio:

Código
  1. if(opcion == 'a' || opcion == 'A')
  2.    {
  3.        cout << "Escriba el nombre de la persona que busca:  "; cin >> nombreBusqueda;
  4.        cout << nombreBusqueda << endl;
  5.        cout << "Buscando..." << endl;
  6.        sleep(2);
  7.        for (i = 0; i < 10; i++)
  8.        {
  9.  
  10.            while(strcmp(nombreBusqueda, arregloPersonas[i].nombre)==0 && i<10)
  11.            {
  12.                cout << "\n\n\nNOMBRE ENCONTRADO!!\n";
  13.                cout << "\n--Informacion de la Persona--";
  14.                cout << "\nNombre de la Persona Buscada:  " << arregloPersonas[i].nombre;
  15.                cout << "\nEdad de la Persona Buscada:  " << arregloPersonas[i].edad;
  16.                i++;
  17.            }
  18.        }
  19.    }
  20.  

Pues lo termine haciendo en C++, pero lo importante es utilizar un ciclo repetitivo dentro de otro ciclo, porque? bueno, como decirlo, fue como un presentimiento, el comportamiento de las cadenas se me hacia sospechoso, algo que pasa como cuando se usan matrices, así que se me ocurrio usarlo, ya sirvio, opte también por quitar lo de NO ENCONTRADO, para no complicarme tanto la vida, igual es un ejercicio, eso es todo.

Vale les agradezco su aporte, su tiempo y esfuerzo, SLDS



Título: Re: [SOLUCIONADO] Busqueda de comparacion de cadenas con arreglo de estructuras
Publicado por: Blaster en 13 Mayo 2015, 20:35 pm
 En primer lugar es innecesario el uso de dos bucles, el uso que das del while puede se fácilmente reemplazado por un if

 Ahora voy a explicarte mas claramente porque no funciona tu código, supongamos que tenemos como entrada pele , luego ingresamos al bucle for de inmediato nos encontramos con la siguiente condición if

Código
  1. if(strcmp(nombreBusqueda, arregloPersonas[i].nombre))

Esto es como decir "si nombreBusqueda es diferente a arregloPersonas.nombre entonces ejecutar la instrucción contenida en el if" en este caso ya que manu chao es diferente a pele pasara a ingresar en el if ejecutando todos los printf y finalmente el break terminara el bucle.

En el caso de que la entrada sea manu chao se hará la comprobación y como obviamente son iguales retornara false por ende pasara a ejecutarse el else mostrando que el nombre no se encuentra en la base de datos y de nuevo el break terminara el bucle

Como seguro te has dado cuenta el bucle solo realiza una iteración siempre por eso te muestra la información del primer elemento únicamente.

Saludos