Cuando fgets ensucia el buffer :S

Iniciado por nicolasblues86, 21 Mayo 2010, 00:57 AM

0 Miembros y 1 Visitante están viendo este tema.

nicolasblues86

Hola a todos!!

bien recien haciendo unas pequeñas pruebas me di cuenta que en ciertas situaciones fgets con stdin... me ensucia el buffer mas especificamente cuando agrego mas caracteres de los que espera doy un ejemplo



#include <stdio.h>

int main(int argc, char **argv)
{
char cad[5];


fgets (cad, sizeof(cad), stdin); //si ingresamos "hola mundo"
puts (cad);                           // imprime "hola"
fgets (cad, sizeof(cad), stdin);// se lo saltea (buffer sucio)
puts (cad);                          // imprime "mun"


return 0;

}





obviamente se puede solucionar haciendo que cad sea mas "grande" como de 120 caracteres, pero quisiera saber alguna manera de no recurrir a eso sino. evitar que el buffer quede sucio....
nada de fflush

EDITADO:
Bueno recién probando encontré que haciendo esto funciona :


setbuf(stdin,NULL); 

 
aunque me vuele a que es algo parecido a fflush


espero respuestas, gracias!!!    



Solamente hay 10 clases de personas en el mundo los que saben leer binario y los que no

Littlehorse

No hay una manera estándar de hacer lo que quieres. El acercamiento con fgets es valido porque no ensucia el buffer en inputs correctos, eso no implica que no lo ensucie si el input es incorrecto. Obviamente cabe destacar que scanf ensucia el buffer sea el input correcto o no.

Para explicarlo a grandes rasgos, cualquier tarea I/O de datos pasa a través de diversos estados. En un nivel mas bajo, es el SO (Alguna capa de abstracción para I/O, o como sea que lo implemente el SO determinado) quien se encarga de las interfaces entre los dispositivos, como por ejemplo el teclado, por lo tanto dichos aspectos son inherentes a cada sistema y no pueden abarcarse todos en un estandar. La idea de las funciones de stdio es tener funciones portables que sirvan para las tareas básicas con esos streams de datos, ahora bien, descartar datos de stdin no es una de esas tareas.

fflush con stdin acarrea comportamiento indefinido, el mero hecho que funcione es simplemente porque algunos fabricantes lo implementan para que funcione, y eso indica claramente la carencia de portabilidad. Similar ocurre con setbuf, como bien dijiste, ya que usarlo de esa manera también acarrea comportamiento indefinido.

El mejor acercamiento es o bien usar un buffer lo suficientemente grande para evitar errores no intencionales y validar el input correctamente para evitar otros errores (intencionales o no). También por supuesto otro acercamiento valido es usar las funciones especificas de cada sistema operativo o implementar tus propias funciones.

Una forma bastante precaria para salir del paso en un descarte simple del input seria algo así:

char cad[5],C;
fgets(cad,5,stdin);
puts(cad);
while((C = getchar()) != '\n' && C != EOF)
;
getchar();


pero por supuesto para desarrollos serios lo ideal seria usar funciones especificas del sistema o desarrollar tus propias implementaciones de dichas funciones (En caso que requieras un control mas estricto del manejo de datos)

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

nicolasblues86

 ;-)  OK!! :D
mil gracias por aclararme las dudas..

Saludos Cordiales
Solamente hay 10 clases de personas en el mundo los que saben leer binario y los que no

Littlehorse

De nada, para eso estamos  :D.

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