2b1c
2b1c

Reputation: 85

How to use fgets properly in a structure?

I can't work out what's the problem with my code. Here's my code:

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

#define N 20

typedef struct _dog {
    char dogName[N],ownerName[N];
    int dogAge;
} Dog;

int main() {
    //Dynamic array
    int size;
    printf("Number of dogs: ");
    scanf("%d", &size);
    Dog *dog = (Dog*)malloc(sizeof(Dog)*size);
    printf("\n");
    //Input
    int i;
    printf("Please provide the data: [dogName][ownerName][dogAge] :\n");
    for(i=0;i<size;i++) {
        fgets(dog[i].dogName, sizeof(dog[i].dogName), stdin);
        fgets(dog[i].ownerName, sizeof(dog[i].ownerName), stdin);
        scanf("%d", &dog[i].dogAge);
    }
    //Output
    printf("\nYou provided the following data:\n");
    for(i=0;i<size;i++) {
        printf("Dog Name: %s\nOwner Name: %s\nDog Age: %d\n", dog[i].dogName, dog[i].ownerName, dog[i].dogAge);
    }

    free(dog);
    return 0;
}

The task is pretty easy, you have to make a database but the dogs and owners can have two or more names, so that's why i try to use fget. But the output looks awful: (And the first Dog name part is usually blank)

You provided the following data:
Dog Name: 

Owner Name: Doggy 1

Dog Age: 0
Dog Name: Big Dick

Owner Name: 2

Dog Age: 0

I've read this but didn't help me.

The input I used:

Doggy 1
Big Dick
2
Doggy 2

It's ended after Doggy 2.

Upvotes: 6

Views: 2144

Answers (2)

Sourav Ghosh
Sourav Ghosh

Reputation: 134296

You are leaving a newline from your last scanf() which is a valid input for the fgets(). Change

scanf("%d", &size);

to

scanf("%d%*c", &size);

to consume and discard the trailing newline due to the press of ENTER key after entering the number of dogs.

The same goes for the dogAge variable scanning, too, inside the lop.

Related, quoting the C11 standard, chapter §7.21.6.2, fscanf()

Trailing white space (including new-line characters) is left unread unless matched by a directive. [...]

so, the newline ('\n'), the trailing white space, is left unread in the input buffer.

Upvotes: 11

Ely
Ely

Reputation: 11152

Add a getchar() after the scanf(...) calls.

As in the other answer(s) mentioned. scanf consumes the recognized characters according to format, but leaves the newline \n in stdin. With getchar you consume it and subsequent reads from stdin should not get confused.

Upvotes: 3

Related Questions