2011-05-10 14 views
11

Si se llama a fclose (0), ¿cierra esto stdin?Si se llama a fclose (0), ¿cierra esto stdin?

La razón por la que estoy preguntando esto es que por alguna razón, stdin se está cerrando en mi aplicación y no puedo entender por qué. Comprobé si fclose (stdin) y esto no está en la aplicación, por lo que me preguntaba si fclose (0) podría causar un comportamiento indefinido, como cerrar stdin.

Si no, ¿qué otras maneras que la entrada estándar están cerradas por error?

+0

fileno (stdin) == 0, pero stdin! = 0 –

+1

¿Está pidiendo * formas * incorrectas de cerrar stdin? Entonces creo que la mayoría de nosotros lo estamos haciendo ahora mismo: -? – cnicutar

+0

¿Estás seguro de que se está cerrando * en * tu aplicación y no * antes * de tu aplicación? ¿'Stdin' funciona correctamente al comienzo de una ejecución de su programa, y ​​luego deja de funcionar en el medio de la ejecución? Si no, tal vez el programa que invocó el suyo se cerró (o nunca configuró) stdin. –

Respuesta

18

La firma de fclose es la siguiente:

int fclose (FILE * stream); 

Eso significa, fclose espera un puntero a FILE objeto. Por lo tanto, si pasa 0, en lugar de un puntero, 0 se entendería como NULL puntero . Si su puntero NULL, ¿cómo espera que cierre stdin? No se cerrará Use fclose(stdin), ya que stdin es un puntero al objeto FILE.

Creo que confunde stdin con el descriptor de archivo que es de tipo integral, y generalmente se denota como fd. Es cierto que fd del flujo de entrada es 0. Por lo tanto, si desea utilizar fd (en lugar de FILE*), debe usar close desde <unistd.h>.

#include <unistd.h> 
int close(int fildes); 

Es decir, close(0) cerraría la entrada estándar.

1: Parece interesante que si hubiera pasado 1 a fclose con la intención de cerrar stdout, su código ni siquiera compilar y se vería de inmediato el problema con su código al mismo tiempo de compilación. Ahora la pregunta es, ¿por qué no compilar? Porque a diferencia de 0, 1 no se convierte implícitamente en tipo de puntero. El compilador generaría un mensaje como "error: invalid conversion from ‘int’ to ‘FILE*’. Vea el error y el número de línea here at ideone.

+1

buena respuesta completa. –

+1

@Nawaz ¿Pero es seguro usar 'fclose (stdin)'? ¿Produce algún comportamiento indefinido? Como en, ¿es diferente de llamar 'close (0)'? –

+1

@Djack: 1) Sí. 2) No. 3) No. – Nawaz

6

Creo que lo tomará como fclose(NULL); Que debería ser indefinido y puede bloquearse.

+3

A veces se define como un bloqueo :) En la página man de Mac OS X: La función fclose() no maneja argumentos NULL; darán lugar a una violación de segmentación – mkb

6

A continuación se cierra la entrada estándar: close(0); fclose(stdin); close(STDIN_FILENO); daemon(0, 0);

5

fclose(0) invoca comportamiento indefinido, así que sí, que podía hacer cualquier cosa, incluyendo el cierre de stdin. Pero tiene problemas mucho más grandes si fclose(0) aparece en su código.

Cuestiones relacionadas