Este é o meu código fonte C.
Quando o construo no Ubuntu, ele começa a obter caracteres, mas não sei como finalizar o programa, pois não termina inserindo ENTERou retornando um carro.
O que significa EOF? Como posso acioná-lo?
Esta fonte também está em um livro 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
stackprogramer
fonte
fonte
-1
é equivalente a EOF. Ele é definido no/usr/include/stdio.h
como uma constante macro-1
como entrada não funciona :) #Respostas:
Tl; dr
Geralmente, você pode "acionar o EOF" em um programa em execução em um terminal com um pressionamento de tecla CTRL+ Dlogo após a última descarga da entrada.
EOF significa Fim do arquivo.
"Disparar EOF" nesse caso significa aproximadamente "conscientizar o programa de que nenhuma entrada será enviada".
Nesse caso, como
getchar()
retornará um número negativo se nenhum caractere for lido, a execução será encerrada.Mas isso não se aplica apenas ao seu programa específico, mas a muitas ferramentas diferentes.
Em geral, "disparar EOF" pode ser feito com um pressionamento de tecla CTRL+ Dlogo após a última descarga da entrada (ou seja, enviando uma entrada vazia).
Por exemplo, com
cat
:O que está acontecendo sob o capô ao pressionar CTRL+ Dé que a entrada digitada desde a última liberação de entrada é liberada; quando isso é uma entrada vazia, o
read()
syscall chamado no STDIN do programa retorna0
,getchar()
retorna um número negativo (-1
na biblioteca GNU C) e, por sua vez, é interpretado como EOF 1 .1 - /programming//a/1516177/4316166
fonte
TL; DR : EOF não é um caractere, é uma macro usada para avaliar o retorno negativo de uma função de leitura de entrada. Pode-se usar Ctrl+ Dpara enviar
EOT
caracteres que forçam o retorno da função-1
Todo programador deve RTFM
Vamos nos referir ao "CA Reference Manual", de Harbison e Steele, 4ª ed. a partir de 1995, página 317:
Essencialmente,
EOF
não é um caractere, mas um valor inteiro implementadostdio.h
para representar-1
. Portanto, a resposta de kos está correta na medida em que isso é válido, mas não se trata de receber entradas "vazias". Nota importante é que aqui o EOF serve como comparação de valor de retorno (degetchar()
), para não significar um caractere real. Osman getchar
suportes que:Considere o
while
loop - seu objetivo principal é repetir a ação se a condição entre colchetes for verdadeira . Olhe novamente:Basicamente, diz continuar fazendo coisas se
c = getchar()
retornar um código bem-sucedido (0
ou acima; é uma coisa comum, tente executar o comando bem-sucedidoecho $?
e, em seguida, falheecho $?
e veja os números que eles retornam). Portanto, se conseguirmos obter o caractere e atribuir a C, o código de status retornado será 0, a falha será -1.EOF
define-se como-1
. Portanto, quando a condição-1 == -1
ocorre, os loops são interrompidos. E quando isso vai acontecer? Quando não há mais caráter para obter, quandoc = getchar()
falha. Você poderia escreverwhile ((c = getchar ()) != -1)
e ainda funcionariaAlém disso, vamos voltar ao código real, aqui está um trecho de
stdio.h
Códigos ASCII e EOT
Embora o caractere EOF não seja um caractere real, no entanto, existe um caractere
EOT
(Fim da transmissão), que possui valor decimal ASCII de 04; está vinculado ao atalho Ctrl+ D(representado também como meta caractere^D
). O caractere de fim da transmissão costumava significar o fechamento de um fluxo de dados quando os computadores eram usados para controlar as conexões telefônicas, daí a denominação "fim da transmissão".Portanto, é possível enviar esse valor ascii para o programa dessa maneira, observe o
$'\04'
que é o EOT:Assim, podemos dizer que existe, mas não é imprimível
Nota
Muitas vezes esquecemos que no passado os computadores não eram tão versáteis - os designers precisam usar todas as teclas do teclado disponíveis. Portanto, o envio de
EOT
caractere com CtrlD ainda está "enviando um caractere", não muito diferente da digitação de letras maiúsculas A, ShiftA, você ainda fornece ao computador uma entrada com as teclas disponíveis. Portanto, a EOT é um personagem real, no sentido de que é proveniente do usuário, é legível por computador (embora não seja imprimível, não é visível por humanos), existe na memória do computadorComentário do Byte Commander
Sim, exatamente certo, porque
/dev/null
não existe um caracter real a ser lido, portanto, elec = getchar()
retornará o-1
código e o programa será encerrado imediatamente. Novamente, o comando não retorna EOF. O EOF é apenas uma variável constante igual a -1, que usamos para comparar o código de retorno da função getchar .EOF
não existe como personagem, é apenas um valor estático por dentrostdio.h
.Demo:
Outro prego no caixão
Às vezes, tenta-se provar que EOF é um personagem com um código como este:
O problema é que o tipo de dados char pode ser um valor assinado ou não assinado. Além disso, eles são o menor tipo de dados endereçável, o que os torna muito úteis em microcontroladores, onde a memória é limitada. Então, em vez de declarar
int foo = 25;
, é comum ver em microcontroladores com pouca memóriachar foo = 25;
ou algo semelhante. Além disso, os caracteres podem ser assinados ou não assinados .Pode-se verificar se o tamanho em bytes com um programa como este:
Qual exatamente é a questão ? O ponto é que o EOF é definido como -1, mas o tipo de dados char pode imprimir valores inteiros .
ESTÁ BEM . . .so e se tentarmos imprimir char como string?
Obviamente, um erro, mas mesmo assim, o erro nos dirá algo interessante:
Valores hexadecimais
Imprimir EOF como um valor hexadecimal fornece
FFFFFFFF
, um valor de 16 bits (8 bytes), o complemento de dois de a-1
.Resultado:
Outra coisa curiosa ocorre com o seguinte código:
Se pressionar Shift+ A, obtemos o valor hexadecimal 41, obviamente o mesmo da tabela ASCII. Mas para Ctrl+ D, temos
ffffffff
novamente o valor de retornogetchar()
armazenado emc
.Consulte outros idiomas
Observe que outro idioma evita essa confusão, porque eles operam na avaliação do status de saída de uma função, não comparando-o com uma macro. Como se lê um arquivo em Java?
E o python?
fonte
/dev/null
, isso também deve retornar um EOF, certo? Ou o que eu chego lá?EOF significa final do arquivo . Embora eu não saiba como acionar o símbolo a seguir, você pode executar o seguinte programa através da canalização de um arquivo, que envia o sinal EOF no final:
onde
a.out
está sua fonte compiladafonte
read()
(syscall) retornará0
, que é interpretada como EOF: stackoverflow.com/a/1516177/4316166