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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top