Programa em C, dúvida

Iniciado por Marmota, 04 de Abril de 2012, 21:57

tópico anterior - próximo tópico

Marmota

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ã.

raidicar

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.

irtigor

Evite o gets, scanf e fflush. Uma saída é a dupla fgets+sscanf (fora uma função pra limpar a entrada).

rudregues

#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.

irtigor

#4
fpurge e __fpurge são outros dois que devem ser evitados (não são padrão nem portáveis).

bred81

Citação de: irtigor 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).
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...

irtigor

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.

fpissarra

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:

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


bred81

Citação de: irtigor 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.
Realmente!
O que o Mario foi fazer no pscicólogo?
- Ele estava passando por uma fase difícil...