Onde é que `getchar ()` armazenar a entrada do usuário?
-
05-07-2019 - |
Pergunta
Eu comecei a ler " A Linguagem de Programação C " (K & R ) e tenho uma dúvida sobre a função getchar()
.
Por exemplo este código:
#include <stdio.h>
main()
{
int c;
c = getchar();
putchar(c);
printf("\n");
}
Digitação toomanychars
+ Ctrl + D (EOF) imprime apenas t
. Eu acho que é esperado, já que é o primeiro caractere introduzido.
Mas então este outro pedaço de código:
#include <stdio.h>
main()
{
int c;
while((c = getchar()) != EOF)
putchar(c);
}
Digitação toomanychars
+ CTRL + D (EOF) gravuras toomanychars
.
A minha pergunta é, por que isso acontece se eu só tenho uma única variável de char? onde está o resto dos personagens são armazenados?
EDIT:
Obrigado a todos pelas respostas, eu começo a obtê-lo agora ... apenas um problema:
O primeiro programa termina quando administrado Ctrl + D enquanto o segundo imprime toda a corda e depois espera por mais entrada do usuário. Por que ele espera por uma outra corda e não sair como o primeiro?
Solução
É tratar o fluxo de entrada como um arquivo. É como se você abriu um arquivo contendo o texto "toomanychars" e ler ou emitidas que um carácter de cada vez.
No primeiro exemplo, na ausência de um tempo loop, é como se você abriu um arquivo e ler o primeiro caractere, e depois emitido lo. No entanto, o segundo exemplo continuará a ler caracteres até que ele recebe um sinal de fim de arquivo (ctrl+D
no seu caso) como se estivesse lendo um arquivo no disco.
Em resposta à sua pergunta atualizado, o sistema operacional você está usando? Corri no meu laptop Windows XP e funcionou muito bem. Se eu bati entrar, seria imprimir o que eu tinha, até agora, fazer uma nova linha, e em seguida continuar. (A função getchar()
não retornar até que você pressione enter, que é quando não há nada no buffer de entrada quando é chamado). Ao pressionar CTRL+Z
(EOF no Windows), as termina programa. Note que no Windows, o EOF deve estar em uma linha própria para contar como um EOF no prompt de comando. Eu não sei se esse comportamento é imitado em Linux, ou qualquer sistema que você pode estar em execução.
Outras dicas
getchar
recebe um único caractere da entrada padrão, que neste caso é o buffer do teclado.
No segundo exemplo, a função getchar
está em um loop while
que continua até encontrar um EOF
, por isso vai manter looping e recuperar um personagem (e imprimir o personagem para a tela) até que a entrada fica vazia.
chamadas sucessivas para getchar
terá caracteres sucessivos que são provenientes da entrada.
Ah, e não se sinta mal por fazer esta pergunta -. Fiquei intrigado quando eu encontrei pela primeira vez esta questão, bem
Algo aqui é tamponado. por exemplo. FILE stdout * que putchar gravações para pode ser line.buffered. Quando as extremidades do programa (ou encontros uma nova linha) tal FILE * será fflush () 'ed e você vai ver o resultado.
Em alguns casos o terminal real que você está vendo pode tamponar a saída até que uma nova linha, ou até que o terminal em si é instruído a eliminá-la do buffer, o que pode ser o caso quando o programa sai do primeiro plano atual sincei que quer apresentar uma novo prompt.
Agora, o que é provável que seja o caso real aqui é que é ele é a entrada que é tamponado (além da saída :-)) Quando você pressiona as teclas que vai aparecer na sua janela de terminal. No entanto, o terminal não vai enviar esses caracteres para a sua aplicação, ele irá tampão até que você instruí-lo a ser o fim-de-entrada com Ctrl + D e, possivelmente, uma nova linha também. Aqui está outra versão para brincar e refletir sobre: ??
int main() {
int c;
while((c = getchar()) != EOF) {
if(c != '\n')
putchar(c);
}
return 0;
}
Tente alimentar seu programa uma frase, e pressione Enter. E fazer o mesmo se você comente if (c! = '\ n') Talvez você possa determinar se a sua entrada, saída ou ambos são tamponados de alguma forma. Isto torna-se mais interessante se você executar a acima como: ./mytest | ./mytest
(Como sidecomment, nota que CTRD + D não é um personagem, nem é EOF. Mas em alguns sistemas que vai resultar fechar o fluxo de entrada que por sua vez irá aumentar EOF para qualquer um que tenta ler a partir do fluxo.)
Seu primeiro programa só lê um caractere, imprime-lo para fora, e sai. O seu segundo programa tem um loop. Ele mantém a leitura personagens um de cada vez e imprimi-los até que ele lê um caractere EOF. Apenas um carácter é armazenado em um determinado momento.
Você só está usando o c
variável para conter cada um carácter de cada vez.
Uma vez que você exibido o primeiro char (t
) usando putchar(c)
, você esquecer-se sobre o valor de c
atribuindo o próximo caractere (o
) ao c
variável, substituindo o valor anterior (t
).
O código é funcionalmente equivalente a
main(){
int c;
c = getchar();
while(c != EOF) {
putchar(c);
c = getchar();
}
}
que você pode encontrar esta versão mais fácil de entender. a única razão para colocar a tarefa no condicional é evitar ter que digitar 'c = getchar ()' duas vezes.
Para a sua pergunta atualizado, no primeiro exemplo, apenas um caractere é lido. Ele nunca chega ao EOF. O programa termina porque não há nada para ele fazer depois de completar a instrução printf. Ele só lê um caractere. Imprime-lo. Coloca em uma nova linha. E depois termina, pois tem mais nada a fazer. Ele não lê mais de um personagem.
Considerando, em que o segundo cigo, o getchar e putchar estão presentes dentro de um tempo de loop. Neste, o programa continua a ler os caracteres um por um (como é feita a fazê-lo pelo laço) até alcances atinge o caractere EOF (^ D). Nesse ponto, ele corresponde c! = EOF e desde que as condições não está satisfeito, ele sai do loop. Agora não há mais declarações para executar. Assim, os termina programa neste ponto.
Espero que isso ajude.