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


 


Tema destacado: BLACK FRIDAY en CiudadWireless!! Útimas unidades de ReadyNAS de Netgear


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  [src]problema con fflush()
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [src]problema con fflush()  (Leído 1,983 veces)
0x3c

Desconectado Desconectado

Mensajes: 108


learning, making mistakes, having fun


Ver Perfil
[src]problema con fflush()
« en: 26 Enero 2013, 22:55 »

Hola, como ya he dicho en otras ocasiones estoy siguiendo un libro para aprender a programar en C, en el capitulo 13 hay un codigo para un programa que se supone lo que hace es comparar dos caracteres...este es el codigo:

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.  char a,b;
  6.  
  7.  printf("Which character is bigger?\n");
  8.  printf("Type a single character:");
  9.  a=getchar();
  10.  printf("Type another character:");
  11.  b=getchar();
  12.  
  13.  if(a > b)
  14.  {
  15.    printf("'%c' is greater than '%c'!\n",a,b);
  16.  }
  17.  else if(b > a)
  18.  {
  19.    printf("'%c' is greater than '%c'!\n",b,a);
  20.  }
  21.  else
  22.  {
  23.    printf("Next time don't press the same character");
  24.  }
  25.  return(0);
  26. }
  27.  

se suponia que todo deberia haber marchado bien, sin embargo segun se explica luego en otras paginas esto no sera asi por que la funcion getchar() solo lee standard input y el output que se odtiene no es el deseado...por lo que (segun dice el libro) hay que agregar una funcion que limpie lo que getchar() mete en la variable 'a'....esa funcion es fflush()..

entonces el codigo quedara asi:

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.  char a,b;
  6.  
  7.  printf("Which character is bigger?\n");
  8.  printf("Type a single character:");
  9.  a=getchar();
  10.  fflush(stdin);
  11.  printf("Type another character:");
  12.  b=getchar();
  13.  
  14.  if(a > b)
  15.  {
  16.    printf("'%c' is greater than '%c'!\n",a,b);
  17.  }
  18.  else if(b > a)
  19.  {
  20.    printf("'%c' is greater than '%c'!\n",b,a);
  21.  }
  22.  else
  23.  {
  24.    printf("Next time don't press the same character");
  25.  }
  26.  return(0);
  27. }
  28.  

el problema es que a pesar de que agrego fflush() el problema persiste el libro sugiere que si todo sigue igual debo agregar fpurge() cosa que el compilador(GCC) me tira un error a causa de esa "funcion"..


!bash-4.2# gcc greater2.c -o greater2
/tmp/cckp5r6k.o: In function `main':
greater2.c:(.text+0x33): undefined reference to `fpurge'
collect2: error: ld returned 1 exit status


entonces me pregunto..estare haciendo algo mal? por que fflush() no funciona? y ademas fpurge() me causa errores, habra otra solucion?


saludos y gracias


En línea

Si Vis Pacem, Para Bellum.

Another Legend Has Fallen
avesudra


Desconectado Desconectado

Mensajes: 644


Intentando ser mejor cada día :)


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #1 en: 26 Enero 2013, 23:04 »

Intenta poniendo esto en lugar de fpurge:
Código
  1. __fpurge()
Otra cosa, fflush no está definido para el estandar de entrada sólo para el de salida.

¡Un saludo!


En línea

Regístrate en
Stakewinner00


Desconectado Desconectado

Mensajes: 1.300



Ver Perfil WWW
Re: [src]problema con fflush()
« Respuesta #2 en: 26 Enero 2013, 23:05 »

el segundo código que pusiste lo compile con g++ y me funciono perfectamente, luego lo probé con gcc y ompila pero no funciona. No se por que pero prueba a compilar con g++.

EDITO: Si colocas un getchar delante se arregla.

Código:
 printf("Which character is bigger?\n");
  printf("Type a single character:");
  a=getchar();
  printf("Type another character:");
  getchar();
  b=getchar();
« Última modificación: 26 Enero 2013, 23:08 por Stakewinner00 » En línea

0x3c

Desconectado Desconectado

Mensajes: 108


learning, making mistakes, having fun


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #3 en: 26 Enero 2013, 23:25 »

Citar
Intenta poniendo esto en lugar de fpurge:
Código

    __fpurge()

intente haciendo eso y obtuve esto:

Código:
!bash-4.2# gcc greater2.c -o greater2
/tmp/ccs0xVLj.o: In function `main':
greater2.c:(.text+0x2b): undefined reference to `_fpurge'
collect2: error: ld returned 1 exit status

Citar
EDITO: Si colocas un getchar delante se arregla.

Código:

  printf("Which character is bigger?\n");
  printf("Type a single character:");
  a=getchar();
  printf("Type another character:");
  getchar();
  b=getchar();

si hago lo que dices si funciona:

Código:
!bash-4.2# ./greater3
Which character is bigger?
Type a single character:j
Type another character:h
'j' is greater than 'h'!

pero por que? no se supone que getchar() espera input?

saludos y gracias
En línea

Si Vis Pacem, Para Bellum.

Another Legend Has Fallen
Stakewinner00


Desconectado Desconectado

Mensajes: 1.300



Ver Perfil WWW
Re: [src]problema con fflush()
« Respuesta #4 en: 26 Enero 2013, 23:33 »

No se por que pasa, haber si alguno de los expertos que corren por aquí nos solventa el misterio.

A otra cosa no te recomiendo mucho usar este truco ya que si existen esas funciones sera siempre mejor intentarlas usarlas, pero alguna vez me paso lo mismo con cin.get() y también puse un cin.get() de más

PD:Tengo un libro de C escrito por un tal Gottfried y solo he leído 2 paginas, en mi opinión es mejor aprender a base de experiencia y luego mirar libros para rellenar los huecos vacíos.
En línea

0x3c

Desconectado Desconectado

Mensajes: 108


learning, making mistakes, having fun


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #5 en: 26 Enero 2013, 23:38 »

Citar
PD:Tengo un libro de C escrito por un tal Gottfried y solo he leído 2 paginas, en mi opinión es mejor aprender a base de experiencia y luego mirar libros para rellenar los huecos vacíos.

no puedo hacer mas que estar de acuerdo :P pero en mi caso ni mi trabajo ni mucho menos mi carrera tienen que ver con programar o hacer codigos...pero tengo planes para los que necesito dominar 'C' por lo menos a medias....





saludos
En línea

Si Vis Pacem, Para Bellum.

Another Legend Has Fallen
avesudra


Desconectado Desconectado

Mensajes: 644


Intentando ser mejor cada día :)


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #6 en: 27 Enero 2013, 00:21 »

Esto ocurre porque un salto de línea queda cojo en el buffer de entrada, depurando tu programa se ve esto en el buffer stdin(que en ese momento termina apuntando al primer 0A):
Código
  1. 77A07EB1  00 00 00 00 00 00 00 00  ........
  2. 77A07EB9  00 00 00 00 00 00 00 61  .......a
  3. 77A07EC1  0A 0A 00 00 00 00 00 00  ........
  4. 77A07EC9  00 00 00 00 00 00 00 00  ........
  5. 77A07ED1  00 00 00 00 00 00 00 00  ........
  6. 77A07ED9  00 00 00 00 00 00 00 00  ........
  7.  
Si te das cuenta los 0A son saltos de línea y al hacer input con scanf se escriben dos por alguna razón que desconozco , entonces al llamar otra vez a getchar y intentar escribir en la siguiente posición del buffer al haber un fin de línea pues es como si ya hubiese escaneado todo el buffer y pasa de largo. El buffer se vería así:
Código
  1. 77A07EC2  0A 00 00 00 00 00 00 00  ........
  2. 77A07ECA  00 00 00 00 00 00 00 00  ........
  3. 77A07ED2  00 00 00 00 00 00 00 00  ........
  4. 77A07EDA  00 00 00 00 00 00 00 00  ........
  5. 77A07EE2  00 00 00 00 00 00 00 00  ........
  6. 77A07EEA  00 00 00 00 00 00 00 00  ........
  7. 77A07EF2  00 00 00 00 00 00 00 00  ........
  8. 77A07EFA  00 00 00 00 00 00 00 00  ........
  9. 77A07F02  00 00 00 00 00 00 00 00  ........
Y al hacer el siguiente getchar pues ya no habría problema porque apuntaría para escribir a la siguiente posición que es una zona vacía.
Para evitar todo esto como ya dijo el moderador Eternal Idol hace mucho tiempo se usa fgets + sscanf. Ya que fgets lee desde un stream , n carácteres ( que le pasas como argumento) menos uno , entonces no lee el fin de línea. Un ejemplo de uso:
Código
  1. #include <stdio.h>
  2.  
  3. int main(int argc, char *argv[])
  4. {
  5.    char cadena[100];
  6.    char buffer[100];
  7.    fgets(buffer,100,stdin);
  8.    sscanf(buffer,"%s",cadena);
  9.    printf("Cadena: %s",cadena);
  10.    return 0;
  11. }
« Última modificación: 27 Enero 2013, 00:27 por avesudra » En línea

Regístrate en
Stakewinner00


Desconectado Desconectado

Mensajes: 1.300



Ver Perfil WWW
Re: [src]problema con fflush()
« Respuesta #7 en: 27 Enero 2013, 00:24 »

Gracias por la explicación
En línea

durasno


Desconectado Desconectado

Mensajes: 376


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #8 en: 27 Enero 2013, 05:58 »

Hola! como ya te dijeron esa "mala lectura" se debe al ENTER(que tambien es un caracter) que queda almacenado en el bufer del teclado, por eso con el segundo getchar no podes ingresar... Otra alternativa para limpiar el bufer seria algo como:
Código
  1. while(getchar()!='\n');/* este bucle debe ir despues de cada getchar*/


Saludos

PD: fpurge no es estandar por eso no te funciona
En línea

Ahorrate una pregunta, lee el man
mr.blood

Desconectado Desconectado

Mensajes: 140


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #9 en: 27 Enero 2013, 11:34 »

Te dejo este codigo, compilado con GCC a mi me funciona sin problema alguno.

Puedes usar setbuff o setbuffer para limpiar el buffer de entrada ;).

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5. char a,b;
  6.  
  7. printf("Which character is bigger?\n");
  8. printf("Type a single character:");
  9. a=getchar();
  10. setbuf(stdin, 0x0); // o fflush(stdin);
  11. printf("Type another character:");
  12. b=getchar();
  13.  
  14. if(a > b)
  15. {
  16.   printf("'%c' is greater than '%c'!\n",a,b);
  17. }
  18. else if(b > a)
  19. {
  20.   printf("'%c' is greater than '%c'!\n",b,a);
  21. }
  22. else
  23. {
  24.   printf("Next time don't press the same character\n");
  25. }
  26. return(0);
  27. }
  28.  

Sa1uDoS
En línea

avesudra


Desconectado Desconectado

Mensajes: 644


Intentando ser mejor cada día :)


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #10 en: 27 Enero 2013, 12:26 »

Pero ¿para que limpiar el buffer? Es que es innecesario, son ganas de ponerse a limpiar el buffer. Usad las funciones correctas y punto. Ya lo zanjó hace tiempo Eternal Idol:
Citar
« Respuesta #3 en: 24 Agosto 2009, 20:13 »
Zanjado: NO USAR JAMAS.

fgets
+
sscanf


Código
  1. #include <stdio.h>
  2.  
  3. int main(int argc, char **argv)
  4. {
  5.    int opcion;
  6.  
  7.    do{
  8.        printf("Opcion: ");
  9. char linea[80];
  10. fgets(linea, sizeof(linea), stdin);
  11.        sscanf(linea, "%d",&opcion);
  12.    }while(opcion!=0);
  13.  
  14.    return 0;
  15. }
Las demás formas de hacerlo son parches para corregir.
Hola! como ya te dijeron esa "mala lectura" se debe al ENTER(que tambien es un caracter) que queda almacenado en el bufer del teclado, por eso con el segundo getchar no podes ingresar... Otra alternativa para limpiar el bufer seria algo como:
Código
  1. while(getchar()!='\n');/* este bucle debe ir despues de cada getchar*/


Saludos

PD: fpurge no es estandar por eso no te funciona
Durasno en ese caso deberías comprobar también si es EOF así que quedaría así:
Código
  1. char c;
  2. while(c=getchar() != '\n' && c != EOF){}
Pero como ya digo son parches. Hacerlo bien no mata a nadie:
Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    char a,b;
  6.    char buffer[80];
  7.  
  8.    printf("Which character is bigger?\n");
  9.  
  10.    printf("Type a single character:");
  11.    fgets(buffer,sizeof(buffer),stdin);
  12.    sscanf(buffer,"%c",&a);
  13.  
  14.    printf("Type another character:");
  15.    fgets(buffer,sizeof(buffer),stdin);
  16.    sscanf(buffer,"%c",&b);
  17.  
  18.    if(a > b)
  19.    {
  20.        printf("'%c' is greater than '%c'!\n",a,b);
  21.    }
  22.    else if(b > a)
  23.    {
  24.        printf("'%c' is greater than '%c'!\n",b,a);
  25.    }
  26.    else
  27.    {
  28.        printf("Next time don't press the same character");
  29.    }
  30.    return(0);
  31. }
¡Un saludo!
« Última modificación: 27 Enero 2013, 12:46 por avesudra » En línea

Regístrate en
durasno


Desconectado Desconectado

Mensajes: 376


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #11 en: 27 Enero 2013, 16:08 »

Citar
Hacerlo bien no mata a nadie
y cual es la forma de hacerlo bien??? lo que indicaste vos??? puede ser, pero solo es una forma, es por eso que se indico varias alternativas... No veo el inconveniente de limpiar el bufer(de echo me gusta mas el bucle que usar fgets+sscanf)


Saludos
En línea

Ahorrate una pregunta, lee el man
avesudra


Desconectado Desconectado

Mensajes: 644


Intentando ser mejor cada día :)


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #12 en: 27 Enero 2013, 16:25 »

y cual es la forma de hacerlo bien??? lo que indicaste vos??? puede ser, pero solo es una forma, es por eso que se indico varias alternativas... No veo el inconveniente de limpiar el bufer(de echo me gusta mas el bucle que usar fgets+sscanf)


Saludos
No claro que no hay inconveniente Durasno, pero es que ¿para qué andar limpiando el buffer si puedes introducir datos sin tener que limpiarlo? A mí también me gusta más el bucle, es más cómodo que hacer fgets + sscanf pero si con fgets + sscanf evito tener que limpiarlo pues prefiero utilizarlo.Además echale un ojo a esto:

http://crasseux.com/books/ctutorial/ y al apartado de http://crasseux.com/books/ctutorial/String-output-and-input.html#String%20output%20and%20input y en concreto esto:

http://crasseux.com/books/ctutorial/Deprecated-formatted-string-input-functions.html#Deprecated%20formatted%20string%20input%20functions

Además acabo de leer que fgets tendría que sustituirlo por getline así que algo que aprendo :)
¡Un saludo!
« Última modificación: 27 Enero 2013, 17:04 por avesudra » En línea

Regístrate en
rir3760


Desconectado Desconectado

Mensajes: 1.486


Ver Perfil
Re: [src]problema con fflush()
« Respuesta #13 en: 30 Enero 2013, 18:40 »

Por partes ...

como ya he dicho en otras ocasiones estoy siguiendo un libro para aprender a programar en C, en el capitulo 13 hay un codigo para un programa que se supone lo que hace es comparar dos caracteres
Te recomendaría buscar otro libro, para sugerencias sobre alguno bueno nada mejor que el motor de búsqueda de los foros.

El programa que publicas tiene deficiencias como: el tipo de retorno de getchar es int, no se vacía explícitamente la salida estándar, vaciar el bufer de la entrada estándar como se indica no es valido, si se va a imprimir una literal es mejor utilizar puts y por ultimo "return(0);" no es una llamada a función y por ende los paréntesis están de mas.

----

Te dejo este codigo, compilado con GCC a mi me funciona sin problema alguno.

Puedes usar setbuff o setbuffer para limpiar el buffer de entrada
En C estándar tampoco vale como solución ya que la llamada a setbuf termina como una llamada a setvbuf y esta ultima debe ser llamada antes de cualquier uso del stream (salvo su apertura).

----

Las demás formas de hacerlo son parches para corregir.Durasno en ese caso deberías comprobar también si es EOF así que quedaría así:
Código
  1. char c;
  2. while(c=getchar() != '\n' && c != EOF){}
Primero la pedantería: el tipo de retorno de la función getchar es int y faltan paréntesis para obtener el resultado esperado:
Código
  1. int ch;
  2.  
  3. /* ... */
  4.  
  5. while ((ch = getchar()) != EOF && ch != '\n')
  6.   ;

Pero como ya digo son parches. Hacerlo bien no mata a nadie:
Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    char a,b;
  6.    char buffer[80];
  7.  
  8.    printf("Which character is bigger?\n");
  9.  
  10.    printf("Type a single character:");
  11.    fgets(buffer,sizeof(buffer),stdin);
  12.    sscanf(buffer,"%c",&a);
  13.  
  14.    printf("Type another character:");
  15.    fgets(buffer,sizeof(buffer),stdin);
  16.    sscanf(buffer,"%c",&b);
  17.  
  18.    if(a > b)
  19.    {
  20.        printf("'%c' is greater than '%c'!\n",a,b);
  21.    }
  22.    else if(b > a)
  23.    {
  24.        printf("'%c' is greater than '%c'!\n",b,a);
  25.    }
  26.    else
  27.    {
  28.        printf("Next time don't press the same character");
  29.    }
  30.    return(0);
  31. }
No puede decirse que la solución en base a un bucle sea un parche cuando, si se piensa un poco, garantiza el descarte de la linea sin importar su longitud, algo que no sucede al utilizar fgets. Por ejemplo si en tu programa la primera linea tiene mas de 79 caracteres su salida no es la correcta.

Opciones hay varias: fgets + sscanf, el mentado bucle o bien scanf mas algunos especificadores de formato. Cual elegir lo decide el contexto.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Powered by SMF 1.1.19 | SMF © 2006-2008, Simple Machines