limpiar c operating-system signals

limpiar - ¿Qué hace fflush(stdin) en la programación en C?



limpiar variables en c (2)

Esta pregunta ya tiene una respuesta aquí:

Soy muy nuevo en la programación de C y estoy tratando de entender cómo fflush(stdin) realmente fflush(stdin) .

En el siguiente ejemplo, ¿ fflush(stdin) borra todo el búfer o borra lo que ingresó después del tercer elemento? Lo que quiero decir es que el usuario ingresa el número de cuenta, el espacio, el nombre, el espacio y el saldo. ¿Es cierto que a partir de este momento, todo lo que ingrese el usuario se fflush(stdin) con fflush(stdin) ? y stdin no estará vacío.

Por qué digo que es porque entra en un bucle while y comienza a escribir en el archivo de texto.

Mi segunda pregunta es si Ctrl-Z le dirá al sistema operativo que deje de pedirle al usuario que ingrese datos.

printf( "Enter the account name and balance. (separated by spaces)/n" ); printf( "Enter EOF to end input. (Ctrl-Z)/n" ); printf( "? " ); scanf( "%d%s%lf", &account, name, &balance ); fflush(stdin); // write account, name and balance into file with fprintf while ( !feof( stdin ) ) { //fflush(stdin); fprintf( cfPtr, "%d %s %.2f/n", account, name, balance ); printf( "? " ); scanf( "%d%s%lf", &account, name, &balance ); } fclose( cfPtr );


La respuesta a esto es que fflush(stream) solo se define formalmente para las secuencias de salida, por lo que fflush(stdout) está bien, pero fflush(stdin) no lo está.

El propósito de fflush(stream) es hacer que el sistema operativo descargue cualquier búfer al archivo subyacente. Para un ejemplo de un uso legítimo, los estudiantes a menudo tienen problemas como "¡mi mensaje no aparece!" Si hacen algo como:

printf("Enter a number: ");

Sin embargo, encuentran que esto funciona bien:

printf("Enter a number:/n");

Por supuesto, no quieren una nueva línea después de su aviso, por lo que tienen un poco de problema.

La razón de esto es que la salida a la salida stdout está almacenada en el búfer por el sistema operativo y el comportamiento predeterminado es (a menudo) solo para escribir realmente la salida en el terminal cuando se encuentra una nueva línea. Agregar un fflush(stdout) después de que printf() resuelva el problema:

printf("Enter a number: "); fflush(stdout);

Ahora, trabajando por analogía, la gente a menudo piensa que fflush(stdin) debería descartar cualquier entrada no utilizada, pero si lo piensa un poco, eso no tiene mucho sentido. ¿Qué significa "vaciar" un búfer de entrada? ¿Dónde está "enrojecido" a ? Si vacia un búfer de salida, la salida se envía al archivo subyacente o al terminal, donde eventualmente terminaría, pero ¿dónde ingresaría "eventualmente terminará"? ¡No hay forma de saberlo! ¿Cuál debería ser el comportamiento si los datos del flujo de entrada provienen de un archivo o una tubería o un socket? No está del todo claro para los flujos de entrada cuál debe ser el comportamiento de fflush() , pero es muy claro para los flujos de salida en todos los casos. Por lo tanto, fflush() solo se define para flujos de salida.

La razón por la que el uso erróneo de fflush(stdin) convirtió en un lugar común es que, hace muchos años, unos pocos sistemas operativos implementaron un esquema en el que funcionó como mucha gente esperaba, descartando las entradas no utilizadas. Microsoft DOS es un buen ejemplo. Sorprendentemente, las versiones modernas de Linux también implementan fflush() para flujos de entrada.

Lo correcto para hacer con una entrada de terminal no deseada "extra" es simplemente leerla y no hacer nada con ella. Esto es casi tan fácil como llamar a fflush(stdin) , funciona en todas partes y no se basa en un comportamiento formalmente indefinido.

El estándar C dice:

Si la secuencia apunta a una secuencia de salida o a una secuencia de actualización en la que no se ingresó la operación más reciente, la función fflush hace que los datos no escritos para esa secuencia se entreguen al entorno del host y se escriban en el archivo; de lo contrario, el comportamiento es indefinido .

POSIX dice (también difiere explícitamente al estándar C ):

Si el flujo apunta a un flujo de salida o un flujo de actualización en el que no se ingresó la operación más reciente, fflush () hará que se escriban en el archivo los datos no escritos de ese flujo, ...

Pero la página de manual de Linux dice:

Para los flujos de salida, fflush () fuerza una escritura de todos los datos almacenados en el espacio del usuario para el flujo de salida o de actualización dado a través de la función de escritura subyacente del flujo. Para las secuencias de entrada, fflush () descarta los datos almacenados en el búfer que se han recuperado del archivo subyacente, pero la aplicación no los ha consumido . El estado abierto de la transmisión no se ve afectado.


fflush(stdin) invoca un comportamiento indefinido.

fflush() está definido solo para flujos de salida. No deberías hacerlo.

En Unix, Ctrl-Z envía una señal TSTP (SIGTSTP) que, de forma predeterminada, hace que el proceso suspenda la ejecución.