1

I'm trying to have the user enter in a number as many times as they want (and create a linked list node for each of the numbers).

However, I've tried multiple method of clearing the character input buffer but to no avail. Strangely, the code will execute once through but not execute correctly the second.

For example, with the code below, the terminal reads:

would you like to enter an integer?
y
Enter an integer: 4
would you like to enter an integer?
y
**program terminates**

And before when I was using scanf("%c", yesno); I would not even be able to input 'y' on the last line. It just terminated.

struct node *read_numbers(void){
    struct node *first = NULL;
    int n; char yesno;
    yesno = 'y';
    while( yesno == 'y'){
        printf("Would you like enter an integer ((y) for yes/(n) for no):\n");
        yesno = getchar();  
        while(getchar() != '\n');
        if(yesno == 'y'){
            printf("Enter an Integer:");
            scanf(" %d", &n);
            first = add_to_list(first, n);
            } else {
                return first;
                }
        } // end while
    }

I read up on character inputs and buffers, and supposedly the getchar() method should work. Am I utilizing it wrong? I've also tried scanf() with extra spaces before and after the "%c", but to no avail.

LazerSharks
  • 3,089
  • 4
  • 42
  • 67

3 Answers3

4

You need to digest the newline after the scanf. You can do what you're doing above in the code:

scanf(" %d", &n);
while(getchar() != '\n');
first = add_to_list(first, n);
Guillaume
  • 2,044
  • 12
  • 11
  • worked! Why do I need `while(getchar() != '\n');` after `scanf()` if, well... I'm using `scanf()` (vs `getchar()`)? – LazerSharks Jun 04 '13 at 01:57
  • @Gnuey because scanf will scan the string until it finds a whitespace character but this character will be left in the read buffer. getchar() reads from that buffer so it will read your newline and get out of the while loop. scanf is clunky. Most people use fgets+sscanf to do what your code does – Guillaume Jun 04 '13 at 02:03
2

Can I recommend that you use fgets as a safer alternative to getchar and scanf?

As you've noticed these functions can buffer the newline and pass it on to the next function that reads from the standard input.

With fgets you can store the input in a char array and avoid such problems. Additionally, you can still check easily if the input consists of only a newline:

char user_input[10] = "";

printf("Would you like enter an integer ((y) for yes/(n) for no):\n");

/* get input or quit if only newline is entered, we only check the first char */
while(fgets(user_input, 3, stdin)[0] != '\n') 
{
    /* check if the first char is 'y', quicker to do than using strcmp */
    if(user_input[0] == 'y') 
    {
        int input = 0;

        printf("Enter an Integer: ");

        fgets(user_input, 5, stdin); /* get input again */

        input = atoi(user_input);    /* convert to int */

        printf("Your integer is %d\n", input);

        printf("Would you like to go again? y/n:\n");
    }
    else
    {
        return printf("No input there.\n");
    }
}
Nobilis
  • 7,310
  • 1
  • 33
  • 67
1

getcharis get the data from stdin, while(getchar() != '\n'); just like clear the stdin buffer. so the following code can work correctly

syler
  • 106
  • 9