Este es mi código fuente C.
Cuando lo compilo en Ubuntu, comienza a obtener caracteres, pero no sé cómo finalizar el programa, ya que no termina ingresando ENTERo un retorno de carro.
¿Qué significa EOF? ¿Cómo puedo activarlo?
Esta fuente también está en un libro de Dennis Ritchie:
#include <stdio.h>
/* count digits, white space, others */
main ()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar ()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf ("digits =");
for (i = 0; i < 10; ++i)
printf (" %d", ndigit[i]);
printf (", white space = %d, other = %d\n", nwhite, nother);
}
command-line
c
programador
fuente
fuente
-1
es equivalente a EOF. Se define/usr/include/stdio.h
como una constante macro-1
como entrada no funciona :)Respuestas:
Tl; dr
En general, puede "disparar EOF" en un programa que se ejecuta en un terminal con una pulsación de tecla CTRL+ Djusto después de la última descarga de entrada.
EOF significa Fin de archivo.
"Activar EOF" en este caso significa "hacer que el programa sea consciente de que no se enviarán más entradas".
En este caso, dado
getchar()
que devolverá un número negativo si no se lee ningún carácter, la ejecución finaliza.Pero esto no solo se aplica a su programa específico, se aplica a muchas herramientas diferentes.
En general, "disparar EOF" se puede hacer con una tecla CTRL+ Djusto después de la última descarga de entrada (es decir, enviando una entrada vacía).
Por ejemplo con
cat
:Lo que sucede debajo del capó al presionar CTRL+ Des que la entrada escrita desde la última descarga de entrada se vacía; cuando se trata de una entrada vacía, la
read()
llamada al sistema llamada en el STDIN del programa devuelve0
,getchar()
devuelve un número negativo (-1
en la biblioteca GNU C) y esto a su vez se interpreta como EOF 1 .1 - /programming//a/1516177/4316166
fuente
TL; DR : EOF no es un carácter, es una macro utilizada para evaluar el retorno negativo de una función de lectura de entrada. Se puede usar Ctrl+ Dpara enviar
EOT
caracteres que forzarán el retorno de la función-1
Todo programador debe RTFM
Consultemos el "Manual de referencia de CA", de Harbison y Steele, 4ª ed. desde 1995, página 317:
Esencialmente
EOF
no es un personaje, sino más bien un valor entero implementadostdio.h
para representar-1
. Por lo tanto, la respuesta de kos es correcta en lo que respecta a eso, pero no se trata de recibir una entrada "vacía". Nota importante es que aquí EOF sirve como valor de retorno (degetchar()
) comparación, no para indicar un carácter real. Losman getchar
apoyos que:Considere el
while
ciclo: su propósito principal es repetir la acción si la condición entre paréntesis es verdadera . Mirar de nuevo:Básicamente dice que siga haciendo cosas si
c = getchar()
devuelve un código exitoso (0
o superior; es algo común por cierto, intente ejecutar un comando exitoso,echo $?
luego fallaecho $?
y vea los números que devuelven). Entonces, si obtenemos con éxito el carácter y asignamos a C, el código de estado devuelto es 0, el error es -1.EOF
se define como-1
. Por lo tanto, cuando se-1 == -1
produce la condición , los bucles se detienen. ¿Y cuándo sucederá eso? Cuando no hay más personajes para obtener, cuandoc = getchar()
falla. Podrías escribirwhile ((c = getchar ()) != -1)
y aún funcionaríaAdemás, volvamos al código real, aquí hay un extracto de
stdio.h
Códigos ASCII y EOT
Aunque el carácter EOF no es un carácter real, existe un carácter
EOT
(Fin de transmisión) que tiene un valor decimal ASCII de 04; está vinculado a Ctrl+ Dacceso directo (representado también como meta carácter^D
). El carácter de fin de transmisión utilizado para significar el cierre de una secuencia de datos cuando las computadoras se usaban para controlar las conexiones telefónicas, de ahí el nombre de "fin de transmisión".Por lo tanto, es posible enviar ese valor ASCII al programa así, tenga en cuenta
$'\04'
cuál es el EOT:Por lo tanto, podemos decir que existe, pero no es imprimible
Nota al margen
A menudo olvidamos que en el pasado las computadoras no eran tan versátiles: los diseñadores tienen que hacer uso de todas las teclas disponibles. Por lo tanto, enviar
EOT
caracteres con CtrlD sigue siendo "enviar un carácter", no muy diferente de escribir mayúscula A, ShiftA, aún puede hacer que la computadora ingrese con las teclas disponibles. Por lo tanto, EOT es un personaje real en el sentido de que proviene del usuario, es legible por computadora (aunque no imprimible, no visible para los humanos), existe en la memoria de la computadoraComentario del comandante de bytes
Sí, exactamente correcto, porque
/dev/null
no hay ningún carácter real para leer, por lo tantoc = getchar()
, devolverá el-1
código y el programa se cerrará de inmediato. De nuevo el comando no devuelve EOF. EOF es una variable constante igual a -1, que usamos para comparar el código de retorno de la función getchar .EOF
no existe como personaje, es solo un valor estático en su interiorstdio.h
.Manifestación:
Otro clavo en el ataúd
A veces se intenta demostrar que EOF es un personaje con un código como este:
El problema con eso es que el tipo de datos char puede ser un valor con signo o sin signo. Además, son el tipo de datos direccionable más pequeño que los hace muy muy útiles en microcontroladores, donde la memoria es limitada. Entonces, en lugar de declarar
int foo = 25;
, es común ver en microcontroladores con poca memoriachar foo = 25;
o algo similar. Además, los caracteres pueden estar firmados o sin firmar .Se podría verificar que el tamaño en bytes con un programa como este:
Cuál es exactamente el punto ? El punto es que EOF se define como -1, pero el tipo de datos char puede imprimir valores enteros .
OKAY . . ¿Qué pasa si intentamos imprimir char como cadena?
Obviamente un error, pero no obstante, el error nos dirá algo interesante:
Valores hexadecimales
Imprimir EOF como un valor hexadecimal da
FFFFFFFF
, un valor de 16 bits (8 bytes), dos cumplidos de a-1
.Salida:
Otra cosa curiosa ocurre con el siguiente código:
Si uno presiona Shift+ A, obtenemos el valor hexadecimal 41, obviamente igual que en la tabla ASCII. Pero para Ctrl+ D, tenemos
ffffffff
, nuevamente, el valor de retorno degetchar()
almacenado enc
.Consulte otros idiomas
Tenga en cuenta que otro lenguaje evita esta confusión, porque operan evaluando el estado de salida de una función, no comparándola con una macro. ¿Cómo se lee un archivo en Java?
¿Qué tal python?
fuente
/dev/null
, eso también debería devolver un EOF, ¿verdad? ¿O qué consigo allí?EOF significa fin de archivo . Si bien no sé cómo activar el siguiente símbolo, puede ejecutar el siguiente programa mediante la canalización de un archivo, que envía la señal EOF al final:
donde
a.out
esta tu fuente compiladafuente
read()
volverá la entrada que se vaciará vacía (syscall)0
, lo que se interpreta como EOF: stackoverflow.com/a/1516177/4316166