elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [Solucionado] Problema con lista enlazada en C (buffer de entrada)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [Solucionado] Problema con lista enlazada en C (buffer de entrada)  (Leído 10,076 veces)
xassiz~


Desconectado Desconectado

Mensajes: 457



Ver Perfil WWW
[Solucionado] Problema con lista enlazada en C (buffer de entrada)
« en: 20 Febrero 2011, 17:02 pm »

#Solucion del post

Bueno, estaba practicando con listas enlazadas en C, pero no se porque no me va esto :xD

El caso es que no me deja ingresar bien los datos, ¿uso mal fgets()?

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4.  
  5. struct _contacto {
  6.    char nombre[33];
  7.    char telefono[13];
  8.    struct _contacto *siguiente;
  9. };
  10. struct _contacto *primero, *ultimo;
  11.  
  12. void agregar_contacto()
  13. {
  14.     struct _contacto *nuevo;
  15.     nuevo = (struct _contacto*)malloc(sizeof(struct _contacto));
  16.     if(nuevo==NULL){
  17.         printf("\nNo hay espacio suficiente.");
  18.         return;
  19.     }
  20.     printf("\n\nAgregar contacto\n");
  21.     printf("------------------");
  22.     printf("\nNombre: ");
  23.     fgets(nuevo->nombre,32,stdin);
  24.     printf("\nTelefono: ");
  25.     fgets(nuevo->telefono,12,stdin);
  26.     nuevo->siguiente = NULL;
  27.     if(primero==NULL){
  28.         primero = nuevo;
  29.         ultimo = nuevo;
  30.     } else {
  31.         ultimo->siguiente = nuevo;
  32.         ultimo = nuevo;
  33.     }
  34. }
  35.  
  36. void buscar_contacto_tlfn()
  37. {
  38.     struct _contacto *busqueda, *actual;
  39.     busqueda = (struct _contacto*)malloc(sizeof(struct _contacto));
  40.     if(busqueda==NULL){
  41.         printf("\nNo hay espacio suficiente.");
  42.         return ;
  43.     }
  44.     printf("\n\nBuscar contacto por telefono\n");
  45.     printf("----------------------------");
  46.     printf("\nTelefono: ");
  47.     fgets(busqueda->telefono,12,stdin);
  48.     actual = primero;
  49.     while(actual!=NULL){
  50.         if(strcmp(actual->telefono,busqueda->telefono)==0){
  51.             printf("+Nombre: %s\n", actual->nombre);
  52.             return;
  53.         }
  54.         actual = actual->siguiente;
  55.     }
  56.     printf("No encontrado.");
  57. }
  58.  
  59.  
  60. int opcion = 0;
  61.  
  62. void mostrar_menu()
  63. {
  64.     opcion = 0;
  65.     printf("\n\n\n MENU\n");
  66.     printf("======\n");
  67.     printf("1. Agregar contacto\n");
  68.     printf("2. Buscar contacto por telefono\n");
  69.     printf("3. Salir\n");
  70.     scanf("%i", &opcion);
  71. }
  72.  
  73. int main()
  74. {
  75.    while(opcion!=3){
  76.        mostrar_menu();
  77.        switch(opcion)
  78.        {
  79.            case 1:
  80.                agregar_contacto();
  81.                break;
  82.            case 2:
  83.                buscar_contacto_tlfn();
  84.                break;
  85.            default:
  86.                break;
  87.        }
  88.    }
  89.    return 0;
  90. }
  91.  

Saludos!


« Última modificación: 21 Febrero 2011, 22:26 pm por pablomi » En línea

Shut

Desconectado Desconectado

Mensajes: 7



Ver Perfil
Re: Problema con lista enlazada en C
« Respuesta #1 en: 20 Febrero 2011, 19:45 pm »

Hola, bueno lo primero que tienes que incluir la libreria <stdlib.h> para usar la malloc. El problema que sugieres al intentar meter los nombres, es porque el fgets suele dar problemas.Es porque se queda en el buffer del teclado el intro y por eso te salta una opcion del menu.Deberias poner antes de cada fgets, fflush(stdin) para limpiar el buffer y que no te salte.


« Última modificación: 20 Febrero 2011, 19:54 pm por Shut » En línea

xassiz~


Desconectado Desconectado

Mensajes: 457



Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #2 en: 20 Febrero 2011, 19:55 pm »

s porque se queda en el buffer del teclado el intro y por eso te salta una opcion del menu.Deberias poner antes de cada gets, fflush(stdin) para limpiar el buffer y que no te salte.
Gracias, funciona, pero en este post fijado dicen que fflush(stdin); es mala costumbre y que lo del buffer debería darme problemas con scanf() pero no con fgets() :-X

« Última modificación: 20 Febrero 2011, 20:02 pm por pablomi » En línea

Shut

Desconectado Desconectado

Mensajes: 7



Ver Perfil
Re: Problema con lista enlazada en C
« Respuesta #3 en: 20 Febrero 2011, 20:05 pm »

Bueno pues entonces si no la quieres usar puedes probar lo del post, es una solucion mejor parece ser, es comprobar si se quedo almacenado un salto de linea en esa posicion, y si es asi mete un nulo. Puedes probar, y si funciona pues mejor. Sino siempre quedara fflush(stdin) xdd

Voi a comprobar yo si me funciona con lo de poner el nulo  :)
En línea

Leber


Desconectado Desconectado

Mensajes: 338


"Fracta, non verba"


Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #4 en: 20 Febrero 2011, 20:31 pm »

Puedes meter un '\0' directamente. Así es como yo lo hago.

Código:
#include <stdio.h>
#include <string.h>

int
main(int argc, char **argv)
{

        char test[20];

                fgets(test, sizeof(test)-1, stdin);
                test[strlen(test)-1] = '\0';
                printf("%s\n", test);
                return 0;
}
En línea

"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
xassiz~


Desconectado Desconectado

Mensajes: 457



Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #5 en: 20 Febrero 2011, 20:44 pm »

Pero lo de cambiar el salto por línea por el caracter nulo sería en el momento de elegir la opción en el menú, ¿no?

En ese caso tengo que reemplazar el scanf() por fgets() y poner la variable opcion como un arreglo de caracteres :-X
En línea

D4RIO


Desconectado Desconectado

Mensajes: 1.004


U N I X


Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #6 en: 21 Febrero 2011, 00:15 am »

Usa readline de GNU
En línea

OpenBSDFreeBSD
Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #7 en: 21 Febrero 2011, 00:47 am »

Las variables globales son perjudiciales para la salud, trata de evitarlas siempre que sea posible.


 
En ese caso tengo que reemplazar el scanf() por fgets() y poner la variable opcion como un arreglo de caracteres :-X
 

Efectivamente. La forma mas segura de realizar un ingreso de datos por parte del usuario es leyendo como texto y luego parseando y validando lo necesario.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
xassiz~


Desconectado Desconectado

Mensajes: 457



Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #8 en: 21 Febrero 2011, 19:06 pm »

Bueno, ya me deshice de variables globales y de los scanf(), pero curiosamente sigue pasando el mismo error :xD

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4.  
  5. struct _contacto {
  6.    char nombre[33];
  7.    char telefono[13];
  8.    struct _contacto *siguiente;
  9. };
  10. struct _contacto *primero, *ultimo;
  11.  
  12. void agregar_contacto()
  13. {
  14.     struct _contacto *nuevo;
  15.     nuevo = (struct _contacto*)malloc(sizeof(struct _contacto));
  16.     if(nuevo==NULL){
  17.         printf("\nNo hay espacio suficiente.");
  18.         return;
  19.     }
  20.     printf("\n\nAgregar contacto\n");
  21.     printf("------------------");
  22.     printf("\nNombre: ");
  23.     fgets(nuevo->nombre,32,stdin);
  24.     printf("\nTelefono: ");
  25.     fgets(nuevo->telefono,12,stdin);
  26.     nuevo->siguiente = NULL;
  27.     if(primero==NULL){
  28.         primero = nuevo;
  29.         ultimo = nuevo;
  30.     } else {
  31.         ultimo->siguiente = nuevo;
  32.         ultimo = nuevo;
  33.     }
  34. }
  35.  
  36. void buscar_contacto_tlfn()
  37. {
  38.     struct _contacto *busqueda, *actual;
  39.     busqueda = (struct _contacto*)malloc(sizeof(struct _contacto));
  40.     if(busqueda==NULL){
  41.         printf("\nNo hay espacio suficiente.");
  42.         return ;
  43.     }
  44.     printf("\n\nBuscar contacto por telefono\n");
  45.     printf("----------------------------");
  46.     printf("\nTelefono: ");
  47.     fgets(busqueda->telefono,12,stdin);
  48.     actual = primero;
  49.     while(actual!=NULL){
  50.         if(strcmp(actual->telefono,busqueda->telefono)==0){
  51.             printf("+Nombre: %s\n", actual->nombre);
  52.             return;
  53.         }
  54.         actual = actual->siguiente;
  55.     }
  56.     printf("No encontrado.");
  57. }
  58.  
  59.  
  60. char mostrar_menu()
  61. {
  62.     char opcion[3];
  63.     printf("\n\n\n MENU\n");
  64.     printf("======\n");
  65.     printf("1. Agregar contacto\n");
  66.     printf("2. Buscar contacto por telefono\n");
  67.     printf("3. Salir\n");
  68.     fgets(opcion,2,stdin);
  69.     return opcion[0];
  70. }
  71.  
  72. int main()
  73. {
  74.    char opcion='0';
  75.    while(opcion!='3'){
  76.        opcion = mostrar_menu();
  77.        if(opcion=='1')
  78.            agregar_contacto();
  79.        else if(opcion=='2')
  80.            buscar_contacto_tlfn();
  81.    }
  82.    return 0;
  83. }
  84.  

Saludos!
« Última modificación: 21 Febrero 2011, 19:08 pm por pablomi » En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Problema con lista enlazada en C
« Respuesta #9 en: 21 Febrero 2011, 19:56 pm »

Es que de la forma que haces la lectura, fgets nunca llega a leer el salto de linea por lo tanto nada puede hacer con el.

Si tenes una cadena de 3 posiciones, y a fgets le pasas como parámetro que lea solo 2, en realidad lee 2-1. Es decir, lee 1 solo carácter, luego agrega el carácter nulo a la cadena, y el salto de linea queda deambulando por el buffer de entrada.


Citar
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first.
A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str.
 A null character is automatically appended in str after the characters read to signal the end of the C string.
Cuando dije leer como texto me referia a leer y analizar una expresion para verificar si el usuario ha ingresado la opción correctamente. Lo que estas haciendo ahora es utilizar una cadena como si fuese un solo carácter y aunque es legal no es del todo correcto.

Saludos!
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines