Clayton Gosse
Clayton Gosse

Reputation: 37

Why does scanf() in this program fail to get input?

First question, why when I run this program does it fail to get user data regarding "scanf(" %d", &books[ctr]->pages);" ? Instead of getting user data it restarts the loop.

Second question, can someone explain why getchar(); is used at the end of the first loop. As stated in the book it says "Clears newline input" but that doesn't really make sense to me. Does this have anything to do with the problem I am having.

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

struct bookInfo {
        char title[40];
        char auth[25];
        float price;
        int pages;
};

int main()
{
    int ctr;
    struct bookInfo * books[3];

    //get info on books

    for (ctr = 0; ctr < 3; ctr++)
    {
        books[ctr] = (struct bookInfo*)malloc(sizeof(struct bookInfo));
        printf("What is the name of the book #%d?\n", (ctr+1));
        fgets(books[ctr]->title, 40, stdin);
        puts("Who is the author? ");
        fgets(books[ctr]->auth, 25, stdin);
        puts("How much did the book cost? ");
        scanf(" $%f", &books[ctr]->price);
        puts("How many pages are in the book? ");
        scanf(" %d", &books[ctr]->pages);
        getchar();
    }

    //print new header and then loop through and print info

    printf("\n\nHere is the collection of books: \n");
    for (ctr = 0; ctr < 3; ctr++)
    {
        printf("#%d: %s by %s", (ctr + 1), books[ctr]->title, books[ctr]->auth);
        printf("\nIt is %d pages and costs $%.2f", books[ctr]->pages, books[ctr]->price);
        printf("\n\n");
    }

    return(0);
}    

I expect this program to gather how many pages are in the book before completing the loop and asking for info regarding the book #2. However....

When I run the program this is what I get...

What is the name of the book #1?

good book

Who is the author? good author

How much did the book cost?

50

How many pages are in the book?

What is the name of the book #2?

bad book

Who is the author?

Upvotes: 1

Views: 143

Answers (1)

Sourav Ghosh
Sourav Ghosh

Reputation: 134276

The problem here is, you never checked the reurn value of scanf()!!

Thus, following the inputs you have shown, for a scanning statement (i.e., the format string) like

 scanf(" $%f", &books[ctr]->price);

an input of 50 will cause a matching failure. Thus, scanf() will return failure and the input will then remain in the input buffer to be consumed by the next successful call to scanf(). In your case, the immediate next conversion specification seems to match exactly the input, so you get the behavior that scanf() never waits for the user input.

Related, quoting C11, chapter §7.21.6.2/P6,

A directive that is an ordinary multibyte character is executed by reading the next characters of the stream. If any of those characters differ from the ones composing the directive, the directive fails and the differing and subsequent characters remain unread. [....]

Upvotes: 4

Related Questions