[RESOLVIDO]Problemas com struct - No win7 funciona e no ubuntu nao

Iniciado por Iago, 05 de Setembro de 2012, 08:40

tópico anterior - próximo tópico

Iago

Olá pessoa, estou com um problema com struct. Crie um vetor de structs pus em um for.  Qquando eu vo ler as próximas posições, ele ja lê o campo nome, sendo q eu coloquei o fflush(stdin); para limpar o buffer, mas não resolveu. Não tenho certeza se o problema esta no ubuntu, pq no win7 funciona. Estou compilando no gcc.

#include <stdio.h>
#include <stdlib.h>

struct cadastro {
   char nome[20];
   int idade;
};

int main(void) {
   struct cadastro empregados[3];
   int i;
   
   for (i = 0; i < 3; i++) {
      printf ("Digite o nome: ");
      fflush(stdin);
      gets (empregados.nome);
      
      printf ("Digite a idade de %s: ", empregados.nome);
      fflush(stdin);
      scanf ("%d", &empregados.idade);
   }
   
   for (i = 0; i < 3; i++) {
      printf ("Nome: %s\n", empregados.nome);
      printf ("Idade: %d", empregados.idade);
      printf ("\n");
   }
   
   return 0;
}

A saída é:

Digite o nome: qwert daflo
Digite a idade de qwert daflo: 99
Digite o nome: Digite a idade de: 999 //Olha ai, ele come o campo nome
Digite o nome: Digite a idade de:  9999
Nome: qwert daflo
Idade: 99
Nome: //Está lendo a idade ao invés do nome
Idade: 99
Nome: //Está lendo a idade ao invés do nome
Idade: 999




Por favor se encontrarem o erro, me expliquem!

fpissarra

Isso acontece porque stdin pode ser bufferizado ou não, dependendo da configuração específica do terminal. De fato, a manpage sobre gets recomenda NÂO usar gets() por ser sucetível a buffer overuns. As observações sobre stdin na manpage 'stdin' (livro 3) falam sobre a bufferização de stdin.

É recomendável, neste caso, o uso de scanf() para ler a string, inclusive especificando o tamanho máximo da string (19 chars, no seu caso):

scanf("%19s", empregados[i].nome);

Outra coisa... fazer flush de stdin não adianta muita coisa, já que o flush é, provavelmente, feito a partir do momento em que vocẽ digita o <ENTER>. O fflush será útil, no entanto, se você o fizer sobre o stdout, já que ele é bufferizado por linha - isto é, o buffer só será descarregado (flushed) automaticamente se for encontrado um '\n' ou quando o buffer ficar cheio.

Assim, troue seu gets() pelo scanf(), como mostrado acima, e troque seus "fflush(stdin)" por "fflush(stdout)".

[]s
Fred

irtigor

É como o fpissarra disse, mude o seu código. A descarga do stdin não está definida no padrão, o resultado pode (vai) variar de compilador, sistema e/ou terminal.

Iago

#3
:) Muito obrigado pela a atenção, explicação e a solução. Mas surgiu um novo problema, não lê espaços. Procurei na internet, mas não resolveu meu problema.
Eles pedem para colocar tipo scanf ("%[A-Z a-z]s", empregados[i].nome); ou scanf ("%[^\n]", empregados[i].nome);

Percebi que com struct não funciona. Se novamente puder me ajudar, ficarei grato.

irtigor

Veja, o importante aqui não é que você use o scanf ou faça fflush do stdout, é que evite o uso do gets e não tente fazer fflush do sdtin, certo? Por exemplo, no manual que fpissarra já citou (man 3 gets), é recomendado substituir o gets por fgets, e é normalmente o que eu faço.

Iago

Vlw pessoa, um colega de faculdade conseguio!
#include <stdio.h>
#include <stdlib.h>

struct cadastro {
   char nome[1024];
   int idade;
};

int main(void) {
   struct cadastro empregados[3];
   int i;

   system("clear");
   for (i = 0; i < 3; i++) {
      printf ("Digite o nome: ");
      scanf("%[^'\n']", empregados[i].nome);
      while (getchar() != '\n');

      printf ("Digite a idade de %s: ", empregados[i].nome);
      scanf ("%d", &empregados[i].idade);
      while (getchar() != '\n');
   }

   for (i = 0; i < 3; i++) {
      printf ("Nome: %s\n", empregados[i].nome);
      printf ("Idade: %d", empregados[i].idade);
      printf ("\n");
   }

   return 0;
}