2012-08-14 20 views
7

Aquí está mi código. Lo ejecuto en ubuntu con terminal. cuando escribo (a CtrlD) en la terminal, el programa no se detuvo, pero continuó esperando mi entrada.ctrl-d no detuvo el tiempo (getchar()! = EOF) loop

No es CtrlD igual a EOF en UNIX?

Gracias.

#include<stdio.h> 

main() { 
    int d; 
    while(d=getchar()!=EOF) { 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
     printf("EOF:%d\n", EOF); 
    } 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
} 
+1

Eso no es recursividad. Es solo un ciclo infinito hasta que EOL la entrada. Recursión = función que se llama directamente o después de algún otro número intermedio de pasos. –

+0

Compilado con gcc, presionar '^ D' detuvo el ciclo por mí. –

+0

@JonLin Simplemente ingrese^D. También funciona para mí. Sin embargo, cuando la entrada es (a^D), el ciclo no se detuvo. – Sam

Respuesta

11

EOF no es un personaje. El EOF es una macro que getchar() devuelve cuando llega al final de la entrada o encuentra algún tipo de error. El ^D no es "un personaje EOF". Lo que sucede en Linux cuando toca^D en una línea es que cierra la secuencia y la llamada getchar() llega al final de la entrada y devuelve la macro EOF. Si escribe ^D en algún lugar en el medio de una línea, la transmisión no se cierra, por lo que getchar() devuelve valores que lee y su bucle no sale.

Consulte el stdio section of the C faq para una mejor descripción.

Además:

En los sistemas modernos, que no refleja ningún carácter real de fin de archivo almacenado en un archivo; es una señal de que no hay más personajes disponibles.

+0

Leo detenidamente el sitio web. En mi opinión, si escribo '^ D' en algún lugar en el medio de una línea, bash abordará'^D'. Como resultado, el programa C no recibió un comando para cerrar la transmisión. Si escribo '^ D' en una sola línea, el programa C obtendrá el comando correcto. ¿Estoy en lo cierto? – Sam

+1

@qingfeng Hay un poco más sobre '^ D' aquí: http://www.c-faq.com/stdio/eofval.html Pero sí, la transmisión no se cerrará a menos que esté en línea por sí mismo. Breve explicación aquí: http://stackoverflow.com/a/1516177/851273 –

+6

Cuando el terminal está en modo canónico, las líneas no se transmiten a través del dispositivo tty hasta que presione enter. Al presionar la tecla EOF configurada (^ D de manera predeterminada), los datos se transmiten inmediatamente y cualquier 'lectura 'esperando a que vuelva con la cantidad de caracteres disponibles. Si la línea ya tiene datos, esta será una lectura normal que no sea de longitud cero. Si la línea está vacía, esto dará como resultado una lectura de longitud cero, que es la * definición * del estado de fin de archivo en un descriptor de archivo. Por lo tanto, la capa stdio lo interpretará como estado EOF. –

6

Además de la respuesta de Jon Lin sobre EOF, no estoy seguro de que el código que escribió sea el que pretendía. Si desea ver el valor devuelto por getchar en la variable d, necesita cambiar su estado de cuenta a while:

while((d=getchar())!=EOF) { 

Esto es debido a que el operador de desigualdad tiene mayor precedencia que la asignación. Por lo tanto, en su código, d siempre sería 0 o 1.

+0

Es muy amable de su parte ser tan meticuloso. Pero solo quiero verificar que la expresión 'd = getchar()! = EOF' es 0 o 1. – Sam

+0

@Sam: Puede dejar en claro que está asignando el resultado de la comparación escribiendo:' while ((d = (getchar()! = EOF))! = 0) 'o como' while ((d = (getchar()! = EOF))) 'para que el compilador no le arroje advertencias. La alternativa más común es 'while ((d = getchar())!! = EOF)' que asigna el resultado de 'getchar()' a 'd' y luego lo compara con EOF. Eso para evitar advertencias del compilador. Muchos compiladores modernos generarán una advertencia por lo que escribiste. –