Search code examples
cstructurescanffgetsgets

C structure not scanning all the inputs


I have this C code:

#include "stdio.h"

main()
{
    struct books
    {
        char name[100],author[100];
        int year,copies;
    }book1,book2;

    printf("Enter details of first book\n");
    gets(book1.name);
    gets(book1.author);
    scanf("%d%d",&book1.year,&book1.copies);

    printf("Enter details for second book\n");
    gets(book2.name);
    gets(book2.author);
    scanf("%d%d",&book2.year,&book2.copies);

    printf("%s\n%s\n%d\n%d\n",book1.name,book1.author,book1.year,book1.copies);
    printf("%s\n%s\n%d\n%d\n",book2.name,book2.author,book2.year,book2.copies);  
}  

What is happening here is that it only scans till the author name of the second book. After that it directly prints the output.

Here is my input:(The first two lines are the initial printf statements)

Enter details of first book
warning: this program uses gets(), which is unsafe.
the c programmign laguagne
dfadsda
3432
23
Enter details for second book
ruby on rails
mark hammers  

After which it directly prints the output:

the c programmign laguagne
dfadsda
3432
23

ruby on rails
0
0

What is wrong here? Also we can see that the name of the second book is assinged to the author.

I'm using gcc as the compiler on Mac OS X ML.


Solution

  • Use fflush(stdin) before each input statement. This method will clear the input buffer. After the modification your code will be-

    #include "stdio.h"
    
    int main()
    {
        struct books
        {
            char name[100],author[100];
            int year,copies;
        }book1,book2;
    
        printf("Enter details of first book\n");
        gets(book1.name);
        fflush(stdin);
    
        gets(book1.author);
        fflush(stdin);
    
        scanf("%d%d",&book1.year,&book1.copies);
        fflush(stdin);
    
        printf("Enter details for second book\n");
        gets(book2.name);
        fflush(stdin);
    
        gets(book2.author);
        fflush(stdin);
        scanf("%d%d",&book2.year,&book2.copies);
    
        printf("%s\n%s\n%d\n%d\n",book1.name,book1.author,book1.year,book1.copies);
        printf("%s\n%s\n%d\n%d\n",book2.name,book2.author,book2.year,book2.copies);  
        return 0;
    } 
    

    You can see the details about fflush() here.

    UPDATED : Here after the scanf() statement you need to flush the input buffer. The fflush() method is not useful here because it is defined only for output streams. You can consume the rest of a partially-read line with a single line code after each scanf() line, like -

    while((c = getchar()) != '\n' && c != EOF);
    

    Than your code will be:

    #include "stdio.h"
    
    int main()
    {
        struct books
        {
            char name[100],author[100];
            int year,copies;
        }book1,book2;
        char c;
        printf("Enter details of first book\n");
        gets(book1.name);
        gets(book1.author);
    
        scanf("%d%d",&book1.year,&book1.copies);
        while((c = getchar()) != '\n' && c != EOF);
    
        printf("Enter details for second book\n");
        gets(book2.name);
        gets(book2.author);
        scanf("%d%d",&book2.year,&book2.copies);
        while((c = getchar()) != '\n' && c != EOF);
    
        printf("%s\n%s\n%d\n%d\n",book1.name,book1.author,book1.year,book1.copies);
        printf("%s\n%s\n%d\n%d\n",book2.name,book2.author,book2.year,book2.copies);  
        return 0;
    } 
    

    OUTPUT :

    Enter details of first book
    warning: this program uses gets(), which is unsafe.
    sadsadas
    asa
    12
    34
    Enter details for second book
    zxczxc
    sds
    23
    22
    sadsadas
    asa
    12
    34
    zxczxc
    sds
    23
    22