Como regra geral para entrada em C, geralmente funciona em linhas - ou seja, é armazenado em buffer. Isso significa que qualquer coisa que você digita não é realmente enviada para o programa até que Enter seja pressionado. Assim, para o primeiro programa, ele está simplesmente aguardando (também chamado de "bloqueio") na solicitação getchar()
até que uma linha de dados chegue. Portanto, ela não vê realmente nada que é digitado até que toda a linha seja enviada.
A linha é enviada na forma de "Isto é uma linha [EOF]" (onde [EOF] é um caractere EOF literal como definido pelo tempo de execução C). O loop no primeiro programa funciona um pouco como uma construção do / while simplesmente pegando caracteres um de cada vez do buffer e imprimindo-os até o final. Como você sabe, Ctrl + D é um sinônimo de shell para EOF. No primeiro programa, quando você pressiona Enter , o cursor se move para o início da próxima linha (observe como não há "\ n" nesse programa, o "\ n" é feito pelo usuário pressionando Enter após a linha de entrada). É por isso que quando você usa Ctrl + D , uma quebra de linha não ocorre, pois não é o próprio programa que produz a quebra de linha, mas o usuário pressiona a tecla Enter chave que produz esta quebra de linha.
O segundo programa é praticamente o mesmo, no entanto, não há loop para a chamada getchar()
. Isso significa que getchar()
é chamado apenas uma vez. Isso obtém o primeiro caractere do buffer de entrada, imprime esse caractere seguido por uma nova linha e, em seguida, sai. Como não há loop para dizer a fazer getchar()
mais de uma vez, é por isso que você só vê um único caractere e não a linha inteira.
Para maior clareza, lembre-se de que a entrada é armazenada em buffer. Então, no segundo programa você pega um único caractere desde o começo do buffer de entrada. No entanto, o restante desses caracteres permanecerá lá até o uso usar outra chamada para recuperá-los. Um erro comum ao iniciar a programação C / C ++ é esquecer de esvaziar o buffer quando você terminar com ele. Caso contrário, esses dados permanecerão lá.
Eu me lembro quando comecei a programar o C ++ (minha primeira língua) e fiquei confuso que eu usaria um código parecido com o seguinte:
#include <iostream>
int main()
{
std::cout << "Enter a sentence: ";
std::string the_sentence;
std::cin >> the_sentence;
std::cout << "\nYou entered: " << the_sentence << std::endl;
std::cout << "Enter another sentence: ";
std::cin >> the_sentence;
std::cout << "\nYou entered: " << the_sentence << std::endl;
return 0;
}
E eu gostaria que um programa de exemplo fosse executado da seguinte forma:
Enter a sentence: Hi my name is Bob!
You entered: Hi
Enter a sentence: (the program would seemingly skip this input block)
You entered: my
Isso ocorre porque a chamada std :: cin só seria lida até o primeiro espaço, deixando o restante da entrada no buffer. Vindo a próxima chamada std :: cin, ela puxou a primeira coisa que ficou no buffer fazendo com que ela ignorasse completamente a fase de entrada real, já que ela já tinha coisas para ler no buffer.
Para liberar o buffer em C, você pode usar algo como
while((c = getchar()) != '\n' && c != EOF);
que é simplesmente uma linha enquanto loop que essencialmente faz a mesma coisa que o loop do primeiro programa, mas simplesmente descarta a entrada
Se eu respondi sua pergunta adequadamente, selecione minha resposta como a melhor resposta. Se não, deixe-me um comentário e tentarei expandir minha resposta ainda mais.