C questões de programação (newbie) [closed]

-3

Eu li Kernighan & amp; Livro de programação Ritchie C agora e tenho algumas perguntas sobre 'getchar' e 'putchar'.

  1. A questão está abaixo do exemplo de código:

    #include <stdio.h>
    int main(void) {
        int c;
        c = getchar();
        while(c != EOF) {
            putchar(c);
            c = getchar();
        }
        return 0;
    }
    

Quando executo este código no terminal e insiro um símbolo (por exemplo, 'i') e pressiono Enter, ele imprime o símbolo inserido:

i // entrou símbolo
eu // símbolo impresso

Depois disso, ele me convida para inserir outro símbolo. Se eu inserir outro símbolo, o procedimento será repetido. Se eu pressionar Ctrl-D (EOF) em vez de inserir outro símbolo, o programa termina. A primeira pergunta é por que quando eu executo este código e depois de inserir um símbolo ('i') e não pressiono Enter, mas pressiono Ctrl-D, ele imprime o símbolo inserido e imprime da seguinte forma:

ii // o primeiro símbolo é inserido, o segundo é impresso após o Ctrl-D

Então, para finalizar o programa, preciso pressionar Ctrl-D novamente.

  1. Por que no código acima eu posso inserir uma palavra e ela imprime uma palavra e, no código abaixo, ela imprime apenas um símbolo, mesmo que eu tenha digitado uma palavra? O código:

    #include <stdio.h>
    
    int main(void) {
        int c;
    
        printf("Enter a character:\n");
        c = getchar();
        printf("Entered character is:\n");
        putchar(c);
        printf("\n");
    
        return 0;
    }
    

Ficarei grato por qualquer ajuda.

    
por Vitaliy Pisnya 01.12.2014 / 10:15

1 resposta

1

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.

    
por Chuck R 01.12.2014 / 11:11