¿Cuál es la diferencia entre usar fflush(stdin) y flushstdin() ? La única diferencia que conozco es que necesito escribir esas cosas vacías antes de usar flushstdin() , pero no sé por qué.
void flushstdin() { int c; while((c = getchar()) != '\n' && c != EOF); } int main () { float a, b, c; float s=0, ar1=0, ar2=0; printf("Inform value of side A"); while(scanf("%f",&a) != 1 || a <= 0){ printf("Invalid value.\n"); flushstdin(); } }y
int main(){ float a,b,c,s=0; printf("Inform value of side A."); while(scanf("%f",&a) != 1 || a<=0){ printf("Invalid value.\n"); fflush(stdin); } }¡Soy un principiante! ¿Qué código es el mejor? O son iguales?
La diferencia es que flushstdin está definido por el usuario y es la única forma en C estándar de vaciar stdin .
fflush es una función de biblioteca estándar. fflush(stdin); invocará un comportamiento indefinido.
c-preguntas frecuentes: 12.26a :
fflushse define solo para flujos de salida . Dado que su definición de "descarga" es completar la escritura de caracteres almacenados en el búfer (no descartarlos), descartar entradas no leídas no tendría un significado análogo parafflushen flujos de entrada.
c-preguntas frecuentes: 12.26b :
No existe una forma estándar de descartar caracteres no leídos de un flujo de entrada de stdio. Algunos proveedores implementan
fflushpara quefflush(stdin)descarte los caracteres no leídos, aunque los programas portátiles no pueden depender de esto . (Algunas versiones de la bibliotecastdioimplementan llamadasfpurgeofabortque hacen lo mismo, pero tampoco son estándar). Tenga en cuenta también que vaciar los búferes de entrada destdiono es necesariamente suficiente: los caracteres no leídos también pueden acumularse en otros, Búferes de entrada a nivel del sistema operativo. Si está tratando de descartar activamente la entrada (quizás anticipándose a emitir un aviso inesperado para confirmar una acción destructiva, para lo cual una "y" escrita accidentalmente podría ser desastrosa), tendrá que usar una técnica específica del sistema para detectar la presencia de entrada escrita anticipadamente; ver preguntas 19.1 y 19.2. Tenga en cuenta que los usuarios pueden sentirse frustrados si descarta una entrada que se escribió demasiado rápido.
Son bastante diferentes. Ambos pueden "vaciar" la entrada, pero en diferentes sentidos de esa palabra.
fflush es una función estándar de C. Su comportamiento en flujos de entrada como stdin no está definido , lo que significa que el estándar C no define su comportamiento.
Algunos sistemas definen el comportamiento de fflush en un flujo de entrada. Por ejemplo en Linux:
Para flujos de entrada,
fflush()descarta cualquier dato almacenado en búfer que se haya obtenido del archivo subyacente, pero que la aplicación no haya consumido.
Puede confiar en fflush(stdin) se comporte de acuerdo con esta descripción si su programa se ejecuta en un sistema basado en Linux o en otro sistema que documenta el mismo comportamiento. El comportamiento de su programa no será portátil; en otros sistemas, podría comportarse de manera arbitrariamente mala. (Lo más probable es que si fflush(stdin) no funciona, no hará nada más que devolver una indicación de error, pero eso no está garantizado).
Su propia función flushstdin hace algo diferente del comportamiento de Linux de fflush(stdin) . Lee y descarta todas las funciones de entrada hasta la primera línea nueva o hasta EOF (que se activa al final del archivo o por un error). Lo hace independientemente de si esa entrada está almacenada en búfer o no.
Por ejemplo, suponga que escribe los caracteres hello (sin una nueva línea), luego su programa llama a fflush(stdin) y luego ingresa una nueva línea.
fflush(stdin) , dado el comportamiento documentado de Linux, descartará el hello y regresará inmediatamente, dejando la nueva línea para que la lea una llamada posterior. "Descarga" stdin en el sentido de que descarta todas las entradas pendientes, independientemente de lo que sea.
Su función flushstdin() leerá y descartará el hello y luego esperará hasta que escriba Enter (o Ctrl-D ), y luego lea y descarte eso. Lee y descarta todas las entradas hasta una nueva línea o EOF, independientemente de si estaba pendiente en el momento de la llamada.
Y nuevamente, el comportamiento de fflush(stdin) no está definido por el estándar C, por lo que usarlo hace que su programa no sea portátil (y su compilador no necesariamente le advertirá sobre eso).
Por cierto, "ese material vacío" es la definición de la función flushstdin . No es necesario para fflush porque es una función de biblioteca C estándar que ya está definida para usted.
Ambas versiones tienen problemas.
Como ya se documentó ampliamente, fflush(stdin) tiene un comportamiento indefinido según el estándar C. La alternativa que usa la función flushstdin() no es mucho mejor. Sugiero leer la entrada estándar una línea a la vez y analizarla con sscanf() , todo en una función de utilidad que puede usar según sea necesario:
int readfloat(const char *prompt, float *val) { char buf[128]; for (;;) { if (prompt) fputs(prompt, stdout); if (!fgets(buf, sizeof(buf), stdin)) { printf("Premature end of file\n"); return 1; } if (sscanf(buf, "%f", val) == 1 && *val > 0) return 0; printf("Invalid value.\n"); } } int main(void) { float a, b, c, s = 0; if (readfloat("Enter value of side A: ", &a)) return 1; ... }