String reading and input buffering

2

I've always used the fgets () function to read keyboard strings, since it (at least I thought so) always clears the input buffer. However, I'm encountering some errors with running the function in the case of the code below. The strings are not being read correctly, it's like I'm using scanf ("% c") and picking up garbage from the input buffer. PS: I know that fflush (stdin) clears the input buffer, but I do not like using this function because it is not portable.

The struct I'm intending to read in the function:

struct Participante
{
    char nome[40];
    char cpf[11];
    char email[20];
    char matricula[15];
    char nascimento[8];
    int ocupacao;
};

The function:

participante* entrada_dados()
{
    participante *part;
    char c;

    part = (participante*) malloc(sizeof(participante));

    printf("Digite o nome do participante \n");
    fgets(part->nome, sizeof(part->nome), stdin);

    printf("Digite o CPF do participante \n");
    fgets(part->cpf, sizeof(part->cpf), stdin);

    printf("Digite o email do participante \n");
    fgets(part->email, sizeof(part->email), stdin);

    printf("Digite a matricula do participante \n");
    fgets(part->matricula, sizeof(part->matricula), stdin);

    printf("Digite a data de nascimento do participante no formato DDMMAAAA \n");
    fgets(part->nascimento, sizeof(part->nascimento), stdin);

    printf("Digite a ocupacao do participante: \n 1- Professor \n 2- Estudante \n");
    scanf("%d", &part->ocupacao);

    return part;

}

Ps2: I am using pointer to structure, as I will return the allocated address and use for building a linked list.

Screen example with error:

    
asked by anonymous 20.09.2015 / 16:33

2 answers

3

Notice that not all input is done with fgets() .

The last part of the participant's occupation is done with scanf() . Do not mix fgets() with scanf() .

If necessary use sscanf() .

    char tmp[12];
    printf("Digite a ocupacao do participante: \n 1- Professor \n 2- Estudante \n");
    if (!fgets(tmp, sizeof tmp, stdin)) /* erro */;
    if (sscanf(tmp, "%d", &part->ocupacao) != 1) /* erro */;
    
20.09.2015 / 16:40
-1

It's very simple, I'll give you a tip that I use a lot.

 struct participante{
char nome[40];
char cpf[11];
char email[20];
char matricula[15];
char nascimento[8];
int ocupacao;}; 
struct participante part;
void p()
{
printf("Digite o nome do participante \n");
scanf("%s",part.nome);

printf("Digite o CPF do participante \n");
scanf("%s",part.cpf);

printf("Digite o email do participante \n");
scanf("%s",part.email);

printf("Digite a matricula do participante \n");
scanf("%s",part.matricula);

printf("Digite a data de nascimento do participante no formato DDMMAAAA \n");
scanf("%s",part.nascimento);

printf("Digite a ocupacao do participante: \n 1- Professor \n 2- Estudante \n");
scanf("%d",&part.ocupacao);

// não precisa dar return pois é só declara a struct como global
}
int main()
{

    p();


} 

Okay, I just tried it, and it works correctly. I always use this in my codes with struct Any questions I'm here

    
21.09.2015 / 23:25