Ir ao conteúdo
  • Cadastre-se

Gets e Scanf


silvioclima

Posts recomendados

Boa tarde !

Tenho uma dúvida em relação ao gets e scanf.

Por exemplo:

for(cont=0;cont<5;cont++)

printf("Digite seu nome: ");

gets(nome); -->>Aqui no segundo loop em diante ele pula e vai para idade;

-->>Eu colocando scanf (ele não lê o nome se tiver espaços;

printf("Digite sua idade: ");

scanf("%d",&idade);

Como eu poderia resolver esta questão ? Obrigado pessoal !.

Link para o comentário
Compartilhar em outros sites

Ola silvioclima,

Bom, o que acontece é que quando você usa uma destas funções de entrada via teclado, o que o programa faz é salvar o que foi digitado num buffer de entrada, e depois grava o que estiver neste buffer na variável que você quiser.

Exemplo: scanf ("%d", &idade);

Quando você digitar "20", o programa grava esse "20" no buffer, e depois a variavel idade pega o que estiver dentro do buffer (Que nesse caso era o "20").

O principal problema com o scanf, é que ele deixa dentro do buffer o "ENTER" que você pressiona para confirmar o que acabou de digitar.

Assim, quando você digita a primeira idade, ele vai "consumir" o numero que voce digitou, mas vai ficar um ENTER gravado no buffer de entrada; Quando o laço volta pro "gets(nome)", o gets lê o ENTER que ficou alocado no buffer, e pula esse comando, deixando o nome vazio (O programa entende que você nao quis colocar nome nenhum, e simplesmente digitou ENTER... Porém esse ENTER você digitou antes)... Ai ele vai direto pro scanf("%d", &idade)...

Enfim, pra solucionar o problema, coloque antes do "gets(nome)" o seguinte comando:

fflush(stdin);

Isso fará com que antes do comando "gets" o programa limpe o buffer de entrada, e assim o gets não lerá mais o ENTER que foi pressionado antes.

Se a explicação ficou confusa, por favor me avise, ok?!

Abraços,

Thiago.

Link para o comentário
Compartilhar em outros sites

  • 1 ano depois...
Ola silvioclima,

Bom, o que acontece é que quando você usa uma destas funções de entrada via teclado, o que o programa faz é salvar o que foi digitado num buffer de entrada, e depois grava o que estiver neste buffer na variável que você quiser.

Exemplo: scanf ("%d", &idade);

Quando você digitar "20", o programa grava esse "20" no buffer, e depois a variavel idade pega o que estiver dentro do buffer (Que nesse caso era o "20").

O principal problema com o scanf, é que ele deixa dentro do buffer o "ENTER" que você pressiona para confirmar o que acabou de digitar.

Assim, quando você digita a primeira idade, ele vai "consumir" o numero que voce digitou, mas vai ficar um ENTER gravado no buffer de entrada; Quando o laço volta pro "gets(nome)", o gets lê o ENTER que ficou alocado no buffer, e pula esse comando, deixando o nome vazio (O programa entende que você nao quis colocar nome nenhum, e simplesmente digitou ENTER... Porém esse ENTER você digitou antes)... Ai ele vai direto pro scanf("%d", &idade)...

Enfim, pra solucionar o problema, coloque antes do "gets(nome)" o seguinte comando:

fflush(stdin);

Isso fará com que antes do comando "gets" o programa limpe o buffer de entrada, e assim o gets não lerá mais o ENTER que foi pressionado antes.

Se a explicação ficou confusa, por favor me avise, ok?!

Abraços,

Thiago.

Perfeito a explicação, me ajudou e muito. Obrigado.:lol:

Link para o comentário
Compartilhar em outros sites

  • 9 anos depois...
Em 03/10/2008 às 16:46, tdtadeu disse:

Bom, o que acontece é que quando você usa uma destas funções de entrada via teclado, o que o programa faz é salvar o que foi digitado num buffer de entrada, e depois grava o que estiver neste buffer na variável que você quiser.

Exemplo: scanf ("%d", &idade);

Quando você digitar "20", o programa grava esse "20" no buffer, e depois a variavel idade pega o que estiver dentro do buffer (Que nesse caso era o "20").

O principal problema com o scanf, é que ele deixa dentro do buffer o "ENTER" que você pressiona para confirmar o que acabou de digitar.

Assim, quando você digita a primeira idade, ele vai "consumir" o numero que voce digitou, mas vai ficar um ENTER gravado no buffer de entrada; Quando o laço volta pro "gets(nome)", o gets lê o ENTER que ficou alocado no buffer, e pula esse comando, deixando o nome vazio (O programa entende que você nao quis colocar nome nenhum, e simplesmente digitou ENTER... Porém esse ENTER você digitou antes)... Ai ele vai direto pro scanf("%d", &idade)...

Enfim, pra solucionar o problema, coloque antes do "gets(nome)" o seguinte comando:

Que explicação TOP! Me salvou!!! Obrigada!!!!

Link para o comentário
Compartilhar em outros sites

Em 21/08/2010 às 21:48, valyassis disse:

...Enfim, pra solucionar o problema, coloque antes do "gets(nome)" o seguinte comando:


fflush(stdin);

@Karol129 Definitivamente não... não use o fflush para limpar o buffer. Existem outras formas melhores de limpar o buffer, mas certamente já é tarde e você n vai voltar mais... Ou sim? >_<

 

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, vangodp disse:

@Karol129 Definitivamente não! Não use o fflush para limpar o buffer. Existem outras formas melhores, mas certamente já é tarde e você n vai voltar mais... Ou sim? >_<

 

Na vdd o professor indicou colocar fseek(stdin,0,SEEK_END); antes do comando gets

Link para o comentário
Compartilhar em outros sites

agora, vangodp disse:

nao entendo? Que se supoe que faz isso?

quando você for ler um texto até a quebra de linha (gets), mas antes o seu programa já leu algum outro dado e deixou
uma quebra de linha pendente. Por exemplo:


printf("Digite sua idade: ");
scanf("%d", &idade);
printf("Digite seu nome completo: ");
fseek(stdin,0,SEEK_END); // ------------- limpeza de buffer
gets(nome);

Link para o comentário
Compartilhar em outros sites

printf("Digite seu nome completo: ");
scanf("%[^\n]%*c"nome);

adicionado 0 minutos depois

😁

adicionado 1 minuto depois

Para ser mais exato:

printf("Digite sua idade: ");
scanf("%d%*c", &idade);
printf("Digite seu nome completo: ");
scanf("%[^\n]%*c"nome); 

 

adicionado 6 minutos depois

Mas é interessante... Nunca vi essa forma com fseek.

Sempre fiz isso:

    int idade;
    char nome[100];
    
    printf("Digite sua idade: ");
    scanf("%d%*c", &idade);
    printf("Digite seu nome completo: ");
    scanf("%[^\n]%*c"nome); 
    
    printf("%d\n", idade);
    printf("%s\n", nome ); 

 

adicionado 8 minutos depois

Se bem isso não limpa o buffer, evita que entre lixo nas variáveis pois o %*c evita o ultimo caractere pulsado, e como o \n é o ultimo então melhor evitar que ter que limpar >_<

adicionado 11 minutos depois

%[^\n] é como se fosse %s porém aceita espaços, aceita tudo até encontrar o enter(\n).

adicionado 12 minutos depois

Existe muitas formas de limpar o buffer. Investigue um pouco porém nunca use fflush >_<

adicionado 14 minutos depois

A explicação do tdtadeu é boa mas a recomendação do fflush para limpar buffer não tanto.

Link para o comentário
Compartilhar em outros sites

13 minutos atrás, vangodp disse:

printf("Digite seu nome completo: ");
scanf("%[^\n]%*c"nome);

adicionado 0 minutos depois

😁

adicionado 1 minuto depois

Para ser mais exato:


printf("Digite sua idade: ");
scanf("%d%*c", &idade);
printf("Digite seu nome completo: ");
scanf("%[^\n]%*c"nome); 

 

adicionado 6 minutos depois

Mas é interessante... Nunca vi essa forma com fseek.

Sempre fiz isso:


    int idade;
    char nome[100];
    
    printf("Digite sua idade: ");
    scanf("%d%*c", &idade);
    printf("Digite seu nome completo: ");
    scanf("%[^\n]%*c"nome); 
    
    printf("%d\n", idade);
    printf("%s\n", nome ); 

 

adicionado 8 minutos depois

Se bem isso não limpa o buffer, evita que entre lixo nas variáveis pois o %*c evita o ultimo caractere pulsado, e como o \n é o ultimo então melhor evitar que ter que limpar >_<

adicionado 11 minutos depois

%[^\n] é como se fosse %s porém aceita espaços, aceita tudo até encontrar o enter(\n).

Daquela forma que o professor me indicou e colocando esse comando que você me ensinou, só funcionou quando eu coloquei primeiro o nome e depois a idade, porque se eu inverter os comandos, deu ruim kkkkk mas obrigada pela dica. Vou anotar aqui. Tô começando agora nessa área e estou com um pouco de dificuldade de entender alguns comandos, mas aqui já me ajudou bastante.

Link para o comentário
Compartilhar em outros sites

https://forum.imasters.com.br/topic/336835-tutorial-systempause-e-fflushstdin/

Aqui tem um debate sobre essas coisas.

adicionado 3 minutos depois

como não deu certo?

Screenshot_7.png.c244386331e75b094dd377cfd5b4379f.png

adicionado 4 minutos depois

voce fez corretamente o que ta na imagem?

adicionado 4 minutos depois

manda seu programa para ver

Link para o comentário
Compartilhar em outros sites

44 minutos atrás, vangodp disse:

Obrigada! 

Utilizei um pouco dos dois conhecimentos, o seu e do meu professor e coloquei dessa forma aqui e deu certo:

 

    int idade, peso;
    char nome[50];
    char estado [30];

 

    printf("Digite sua idade: ");
    scanf("%d%*c", &idade); // aqui o %*c evitou que o enter entrasse na variável nome
    printf("Digite seu nome completo: ");
    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
    printf("digite seu peso: ");
    scanf("%d", &peso); // aqui não foi necessário o %*c porque não li nenhum texto após o enter

 

Obrigada!

Link para o comentário
Compartilhar em outros sites

Está funcionando corretamente? Porque me adimira que nesta parte...

    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
 

...logo depois de ler nome você consiga ler estado sem precisar intervir. Esses erros dão quando você tenta ler um char ou string logo depois de ler qualquer outra coisa como um int, um float, etc, porque você sempre aperta o enter ao executar o programa ao fazer uma leitura. É dizer... cada vez que pulsar enter pode dar erro porque o enter pode estar no buffer. si nao ponha o fseek antes de ler o estado, sei lá. >_<

Sempre faça a prova para ver se o programa funciona.

Outra coisa é usar essa função para vaziar o buffer:
 

void flush() {
    //funçao excelente para limpar o buffer de entrada.
    int ch;
    while ( ( ch = fgetc ( stdin ) ) != EOF && ch != '\n' ) {}
}

chamar ela antes de usar qualquer leitura de string ou char vai servir para ter o buffer limpo.
Isso tudo já foi comentado aqui:
https://www.clubedohardware.com.br/forums/topic/1218096-limpar-buffer-em-c/

Link para o comentário
Compartilhar em outros sites

Eu costumo colocar um espaço em branco antes da máscara do scanf, assim ele ignora o ENTER que possa estar contido no buffer. Dessa forma funciona independente do que você lê primeiro:

#include <stdio.h>

int main() {
    int idade = 0;
    char nome[255] = "";

    for (int i = 0; i < 3; ++i) {
        printf("Digite a sua idade: ");
        scanf(" %i", &idade);

        printf("Digite o seu nome: ");
        scanf(" %[^\n]", nome);
    }

    return 0;
}

 

adicionado 0 minutos depois

Não sei se é uma boa ideia, mas funciona e é bem simples e discreta também.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

59 minutos atrás, vangodp disse:

Está funcionando corretamente? Porque me adimira que nesta parte...

    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
 

...logo depois de ler nome você consiga ler estado sem precisar intervir. Esses erros dão quando você tenta ler um char ou string logo depois de ler qualquer outra coisa como um int, um float, etc, porque você sempre aperta o enter ao executar o programa ao fazer uma leitura. É dizer... cada vez que pulsar enter pode dar erro porque o enter pode estar no buffer. si nao ponha o fseek antes de ler o estado, sei lá. >_<

Sempre faça a prova para ver se o programa funciona.

Outra coisa é usar essa função para vaziar o buffer:
 


void flush() {
    //funçao excelente para limpar o buffer de entrada.
    int ch;
    while ( ( ch = fgetc ( stdin ) ) != EOF && ch != '\n' ) {}
}

chamar ela antes de usar qualquer leitura de string ou char vai servir para ter o buffer limpo.
Isso tudo já foi comentado aqui:
https://www.clubedohardware.com.br/forums/topic/1218096-limpar-buffer-em-c/

 

59 minutos atrás, vangodp disse:

Está funcionando corretamente? Porque me adimira que nesta parte...

    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
 

...logo depois de ler nome você consiga ler estado sem precisar intervir. Esses erros dão quando você tenta ler um char ou string logo depois de ler qualquer outra coisa como um int, um float, etc, porque você sempre aperta o enter ao executar o programa ao fazer uma leitura. É dizer... cada vez que pulsar enter pode dar erro porque o enter pode estar no buffer. si nao ponha o fseek antes de ler o estado, sei lá. >_<

Sempre faça a prova para ver se o programa funciona.

Outra coisa é usar essa função para vaziar o buffer:
 


void flush() {
    //funçao excelente para limpar o buffer de entrada.
    int ch;
    while ( ( ch = fgetc ( stdin ) ) != EOF && ch != '\n' ) {}
}

chamar ela antes de usar qualquer leitura de string ou char vai servir para ter o buffer limpo.
Isso tudo já foi comentado aqui:
https://www.clubedohardware.com.br/forums/topic/1218096-limpar-buffer-em-c/

Funcionou sim, amigo! Como após o nome eu também executei um comando de texto, não precisei colocar "%*c", mas se eu tivesse que ler uma variável inteira, aí sim eu precisaria colocar:

 int idade, peso;
    char nome[50];
    char estado [30];

    printf("Digite sua idade: ");
    scanf("%d%*c", &idade); // aqui o %*c evitou que o enter entrasse na variável nome
    printf("Digite seu nome completo: ");
    gets(nome);

    printf("digite seu peso: ");
    scanf("%d%*c", &peso); // aqui não foi necessário o %*c porque não li nenhum texto após o enter
    printf("digite seu estado: ");
    gets(estado);

 

image.thumb.png.a9dccd3228889034b81895e1f3e3716a.png

 

adicionado 10 minutos depois
1 hora atrás, vangodp disse:

Está funcionando corretamente? Porque me adimira que nesta parte...

    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
 

...logo depois de ler nome você consiga ler estado sem precisar intervir. Esses erros dão quando você tenta ler um char ou string logo depois de ler qualquer outra coisa como um int, um float, etc, porque você sempre aperta o enter ao executar o programa ao fazer uma leitura. É dizer... cada vez que pulsar enter pode dar erro porque o enter pode estar no buffer. si nao ponha o fseek antes de ler o estado, sei lá. >_<

Sempre faça a prova para ver se o programa funciona.

Outra coisa é usar essa função para vaziar o buffer:
 


void flush() {
    //funçao excelente para limpar o buffer de entrada.
    int ch;
    while ( ( ch = fgetc ( stdin ) ) != EOF && ch != '\n' ) {}
}

chamar ela antes de usar qualquer leitura de string ou char vai servir para ter o buffer limpo.
Isso tudo já foi comentado aqui:
https://www.clubedohardware.com.br/forums/topic/1218096-limpar-buffer-em-c/

Na real, funcionou das duas formas:

assim:

 int idade, peso;
    char nome[50];
    char estado [30];

    printf("Digite sua idade: ");
    scanf("%d%*c", &idade); // aqui o %*c evitou que o enter entrasse na variável nome
    printf("Digite seu nome completo: ");
    gets(nome);

    printf("digite seu peso: ");
    scanf("%d%*c", &peso); // aqui não foi necessário o %*c porque não li nenhum texto após o enter
    printf("digite seu estado: ");
    gets(estado); 

 

 

e assim:

 

    int idade, peso;
    char nome[50];
    char estado [30];

    printf("Digite sua idade: ");
    scanf("%d%*c", &idade); // aqui o %*c evitou que o enter entrasse na variável nome
    printf("Digite seu nome completo: ");
    gets(nome);

    printf("digite seu estado: ");
    gets(estado);
    printf("digite seu peso: ");
    scanf("%d", &peso); // aqui não foi necessário o %*c porque não li nenhum texto após o enter

 

Pelo que eu entendi, você só precisa colocar o "%*c" após colocar uma variável do tipo inteiro onde logo o próximo comando vai ser uma variável do tipo caractere. Fora dessa condição, não precisa colocar. Fiz o teste aqui e deu certo hehe

adicionado 13 minutos depois
1 hora atrás, AdrianoSiqueira disse:

Eu costumo colocar um espaço em branco antes da máscara do scanf, assim ele ignora o ENTER que possa estar contido no buffer. Dessa forma funciona independente do que você lê primeiro:


#include <stdio.h>

int main() {
    int idade = 0;
    char nome[255] = "";

    for (int i = 0; i < 3; ++i) {
        printf("Digite a sua idade: ");
        scanf(" %i", &idade);

        printf("Digite o seu nome: ");
        scanf(" %[^\n]", nome);
    }

    return 0;
}

 

adicionado 0 minutos depois

Não sei se é uma boa ideia, mas funciona e é bem simples e discreta também.

Vou tentar aqui. Obrigada!!!

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...