Autor Tópico: Programa em C, dúvida  (Lida 3443 vezes)

Offline Marmota

  • Usuário Ubuntu
  • *
  • Mensagens: 15
  • Xubuntu 11.10 64 bit
    • Ver perfil
Programa em C, dúvida
« Online: 04 de Abril de 2012, 21:57 »
Boa noite pessoal! Estou começando agora em C (uso o Code::Blocks).

Estou com um código simplíssimo, mas que não acho a falha!

#include <stdio.h>

int main(void)
{
    char A[10];
    int x=1;
    while(x!=0)
    {
        printf("Digite a string: ");
        gets(A);
        printf("Digite '0' para sair. ");
        scanf("%d", &x);
    }
    return 0;
}

O primeiro gets() ele pega, mas nas próximas iterações ele passa direto pelo gets() e pede apenas o scanf().
Será buffer overflow? Alguma idéia sobre como solucionar usando o gets?
O computador acaba com minha coluna e visão, o fone de ouvido acaba com minha audição. Vivo como se não houvesse amanhã.

Offline raidicar

  • Usuário Ubuntu
  • *
  • Mensagens: 576
  • Quad Shot of Ubuntu
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #1 Online: 05 de Abril de 2012, 13:22 »
já tentou inserir fflush(stdin); entre o printf e o scanf ?
Quem ama extremamente, deixa de viver em si e vive no que ama. Na vida três coisas são certas, o amor, a morte e o Linux !
Se Platão disse, então realmente sofremos de uma perigosa doença mental.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #2 Online: 05 de Abril de 2012, 14:08 »
Evite o gets, scanf e fflush. Uma saída é a dupla fgets+sscanf (fora uma função pra limpar a entrada).

Offline rudregues

  • Usuário Ubuntu
  • *
  • Mensagens: 388
  • Fight!
    • Ver perfil
    • Dieta Paleo
Re: Programa em C, dúvida
« Resposta #3 Online: 05 de Abril de 2012, 14:14 »
Código: [Selecionar]
#include <stdio.h>

int main(void)
{
    char A[10];
    int x=1;
    while(x!=0)
    {
        printf("Digite a string: ");
        gets(A);
        __fpurge(stdin);
        printf("Digite '0' para sair. ");
        scanf("%d", &x);
        __fpurge(stdin);
    }
    return 0; 
}

Aqui funcionou...
fonte: http://www.vivaolinux.com.br/topico/C-C++/fflush%28stdin%29;/

  [ ]'s
Gentoo — Controle total sobre o sistema.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #4 Online: 05 de Abril de 2012, 14:35 »
fpurge e __fpurge são outros dois que devem ser evitados (não são padrão nem portáveis).
« Última modificação: 05 de Abril de 2012, 21:07 por irtigor »

Offline bred81

  • Usuário Ubuntu
  • *
  • Mensagens: 971
  • HAN?!
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #5 Online: 05 de Abril de 2012, 15:51 »
Evite o gets, scanf e fflush. Uma saída é a dupla fgets+sscanf (fora uma função pra limpar a entrada).
Discordo sobre o scanf.
Se configurado direito, ele pode ser usado, ao contrário do que mostra o link.

Melhor maneira seria passar para um "* char" e depois usar a função "atoi" (posix) para pegar a parte inteira do número (pelo visto, o que a pessoa que fez esse link queria).
O que o Mario foi fazer no pscicólogo?
- Ele estava passando por uma fase difícil...

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #6 Online: 05 de Abril de 2012, 21:06 »
Disse evitar... mesmo que seja possível fazer o que o autor queria, existem outros motivos, como a "mania" de deixar caracteres no buffer de entrada (problema que o Marmota está vivenciando).

O mais importante é conhecer os pontos fracos, até por isso, recomendo os outros textos que aparecem no link.

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Programa em C, dúvida
« Resposta #7 Online: 06 de Abril de 2012, 19:21 »
Srs,

O problema com o gets() é tão somente a possibilidade de obter um buffer overrun, se o ponteiro não apontar para um buffer de tamanho suficiente. Por isso ele deve ser evitado.

Já os file descriptors stdin e stdout são bufferizados até que um caracter \n seja encontrado. Nesse caso, e no caso do buffer ficar cheio, um fflush() é automaticamente chamado pela libc.

O código do Marmota provavelmente está sofrendo do seguinte comportamento: As funções gets() e scanf() parecem estar sendo chamadas antes das chamadas a printf(). Não é o caso... como não existem caracteres \n no fim das strings, então o buffer é preenchido e não mostrado (até enchê-lo... tipicamente a libc determina um buffer de 128 bytes, mas isso pode ser mudado via função setvbuf().

Ou seja, stdout é bufferizado por linha. O descritor stderr, por outro lado, não tem esse problema. Ele não é bufferizado! Para evitar o buffering em stdout pode-se usar:

Código: [Selecionar]
setvbuf(stdout, NULL, _IONBUF, 0);
Já stdin, bufferizado ou não, neste caso, não faz diferença, já que o a tecla <ENTER> (\n) e usada para aceitar a entrada do usuário, descarregando o buffer.

[]s
Fred


Offline bred81

  • Usuário Ubuntu
  • *
  • Mensagens: 971
  • HAN?!
    • Ver perfil
Re: Programa em C, dúvida
« Resposta #8 Online: 09 de Abril de 2012, 00:26 »
Disse evitar... mesmo que seja possível fazer o que o autor queria, existem outros motivos, como a "mania" de deixar caracteres no buffer de entrada (problema que o Marmota está vivenciando).

O mais importante é conhecer os pontos fracos, até por isso, recomendo os outros textos que aparecem no link.
Realmente!
O que o Mario foi fazer no pscicólogo?
- Ele estava passando por uma fase difícil...