0

I am new to programming in C, so I decided to make a book library for practice. Working on a function to add a new book i need to get the book name, the authot name and the book quantity. But the program prints asking for all of them and i want to ask for another after the input is given, on the screen it should look like this:

Author: input author name

Title: input book title

Quantity: input book quantity

To get the author and book names I am using fgets, because both of them are strings, but for some reason it keeps printing and the result I am getting is:

Author:

Title:

input line for author name

input line for book title

Quantity: input book quantity

Is there a problem with my code? Or a way to make it the way I want?

book generate_book(book entry, library lib) {
    printf("You must tell me the info about the book\n");
    printf("Author: ");
    fgets(entry.author, 50, stdin);
    fflush(stdin);
    printf("Title: ");
    fgets(entry.title, 50, stdin);
    fflush(stdin);
    printf("Quantity: ");
    scanf("%d", &entry.quantity);
    fflush(stdin);
    entry.id = lib.used_space + 1;
    entry.issued = 0;
    return entry;
}

This function is called after a choice made in a menu using switch case with integer variables

Luís Otávio
  • 183
  • 1
  • 13
  • 2
    My *guess* is that somewhere before the code you show, you're using `scanf` which leaves the newline from the `Enter` key in the input buffer, which `fgets` reads as an empty line. Please [edit] your question to include a proper [mcve]. – Some programmer dude Jul 15 '20 at 14:27
  • 1
    Use **only** `fgets()` for user input. `scanf();` ==> `fgets(); sscanf();` – pmg Jul 15 '20 at 14:28
  • `printf("Title: ")` will not write anything to stdout (assuming stdout is line buffered). No data will be written until either you flush the buffer or try to print a newline. `fgets` is going to block, waiting for input from stdin. – William Pursell Jul 15 '20 at 14:28
  • Yeah, i have a menu before that, and it was not flushed, but even after doing that it didn't work – Luís Otávio Jul 15 '20 at 14:32
  • 2
    Use **only** `fgets()` for user input, even for that previous menu – pmg Jul 15 '20 at 14:37
  • fgets works for integer? – Luís Otávio Jul 15 '20 at 14:38
  • couple `fgets()` with `sscanf()` ot `strtol()`, eg `fgets(line, sizeof line, stdin); int k = strtol(line, 0, 10);` or `fgets(line, sizeof line, stdin); sscanf(line, "%d", &k);` – pmg Jul 15 '20 at 14:39
  • Yeah, it worked! Thanks! I did not knew the `sscanf()` nor the `strtol()` functions, so I'll check more on them as well – Luís Otávio Jul 15 '20 at 14:46
  • Note that passing an input-only stream (like `stdin`) to `fflush` is explicitly mentioned in the C specification as leading to *undefined behavior*. Some systems add it as a non-standard and non-portable extension, so it should really be avoided. To "flush" the input read character by character in a loop until you get either a newline or `EOF`. – Some programmer dude Jul 15 '20 at 14:46
  • Please provide a reproducible example. You have used some structures in there without knowing the definition of which, we have no way of validating your code. – th33lf Jul 15 '20 at 15:20
  • [`fflush(stdin);` is undefined behaviour, don't do it.](https://stackoverflow.com/a/38325926/2173917)"} – Sourav Ghosh Jul 15 '20 at 15:20
  • The [Microsoft documentation for `fflush()`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fflush?view=vs-2019) changed since I last looked. It now reads: *"... If the stream was opened in read mode [...] the call to fflush has no effect ..."* – pmg Jul 15 '20 at 20:19

0 Answers0