Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use fgets properly in a structure?

Tags:

c

fgets

scanf

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.

like image 973
2b1c Avatar asked Dec 27 '15 14:12

2b1c


2 Answers

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.

like image 125
Sourav Ghosh Avatar answered Nov 04 '22 18:11

Sourav Ghosh


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.

like image 33
Ely Avatar answered Nov 04 '22 19:11

Ely