1

I'm trying to use fgets to obtain user input from the command line. The code snippet is part of a function that allows users to add new nodes to a singly linked list. As you can see from my code, I use a while loop to keep requesting input from the user (so that he/she can add more than one node). When I run the program, everything is fine the first time. When I try to add a second node, however, the program skips the input request for the first name field. In my command line, I get First name: Last name:

while (go)
{
    char first_name[256];
    char last_name[256];
    char telephone[256];
    char address[256];

    printf("First name: ");
    fflush(stdout);
    fgets(first_name, sizeof(first_name), stdin);
    //scanf("%s", &first_name);
    fflush(stdin);

    printf("Last name: ");
    fflush(stdout);
    fgets(last_name, sizeof(last_name), stdin);
    fflush(stdin);
    //scanf("%s", &last_name);

    printf("Address: ");
    fflush(stdout);
    fgets(address, sizeof(address), stdin);
    fflush(stdin);
    //scanf("%s", &address);

    printf("Telephone: ");
    fflush(stdout);
    fgets(telephone, sizeof(telephone), stdin);
    fflush(stdin);
    //scanf("%s", &telephone);

    if (!search_by_all(first_name, last_name, address, telephone))
    {
        add_entry(first_name, last_name, address, telephone);
        printf("Success adding entry! Add another entry? 1 for yes, 0 for no.\n");
        scanf("%d", &go);
        fflush(stdin);
        fflush(stdout);
    }
    else
    {
        printf("Error adding entry. Quitting...\n");
        break;
    }
}

I have looked at similar questions on stackoverflow and other sites, but flushing stdin and stdout don't do the trick for me. Neither does allocating more space in my buffers. Any suggestions? Thanks!

Bec
  • 133
  • 4
  • 5
  • 13
  • 2
    Why `fflush(stdin)` ? Isn't that undefined behaviour, at least on most platforms? – Martin R Jan 29 '14 at 18:06
  • don't use `fflush(stdin);` if you are not using Microsoft compiler – Grijesh Chauhan Jan 29 '14 at 18:07
  • possible duplicate of [Why fgets is not inputting first value?](http://stackoverflow.com/questions/20092468/why-fgets-is-not-inputting-first-value) – Barmar Jan 29 '14 at 18:09
  • I used fflush because I saw that as a suggestion to resolve a similar problem. But I should avoid it? – Bec Jan 29 '14 at 18:14
  • 2
    This is probably third post today with the same problem. You `scanf` does not read the newline which you've typed when entering `go`. The newline is then read by the next fgets as an empty line and confusing your program. Add a space after `%d`, i.e. `scanf("%d ", &go);` – Marian Jan 29 '14 at 18:36
  • Hi Marian, your solution did not work for me. – Bec Jan 29 '14 at 19:51
  • 1
    @Marian The suggested `scanf("%d ", &go);` does not work because `scanf()` will not return until some non-white-space is entered after the `int` such as `"123\nX"`. This non-white-space read by `scanf()` terminates the `' '` directive that you are advocating. `scanf()` then puts this non-white-space back into `stdin` for the next I/O operation. Further, `stdin` is typically buffered, so the `'X'` is not seen until a `'\n'` follows it obliging the user to enter `"123\nX\n"`. – chux - Reinstate Monica Jan 29 '14 at 20:29
  • `scanf("%d", &go);` --> `scanf("%d%*c", &go);` : `%*c` read and drop `'\n'`. – BLUEPIXY Jan 29 '14 at 23:31

1 Answers1

1

Mixing scanf() and fgets() is problematic.

Suggest all fgets() and check results.

// scanf("%d", &go);
char buf[sizeof(go)*3 + 3];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
if (sscanf(buf, "%d", &go) != 1) Handle_BadInput;

The typical usage of scanf() leaves the Enter or '\n' in stdin. A subsequent call to fgets() then returns only "\n".

Note: Confident all occurrences of fflush(stdin); may be removed.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256