0

I am making a little program that takes as input the answer to the question "Are you an adult?" as a character like that:

bool adult() {
    char answer;
    do {
        printf("Are you an adult? [y/n]\n");
        answer = getchar();
    } while (!(answer == 'y' || answer == 'n'));

    return (answer == 'y');
}

My aim was that the question should repeat itself if the answer is neither y or n. But this seems to have a bug:

When I answer something else (neither y or n), the question gets printed twice:

Are you an adult? u Are you an adult? Are you an adult? ...

Why is this happening? Also, I've tried the same method with scanf instead of getchar but there is the same bug. For this kind of program, should I use scanf or getchar and why?

Thanks!

pavlos163
  • 2,730
  • 4
  • 38
  • 82

2 Answers2

5

Actually the extra '\n' in the answer with (yes) y or (no) n gets counted and it's printed twice. You just remember to get that dummy '\n'. Use another extra getchar(). The dummy getchar() is a solution to this problem.

bool adult() {
    char answer;
    do {
        printf("Are you an adult? [y/n]\n");
        answer = getchar();
        getchar(); //~~~~~~~~~~~~~~~~~~~~> this is what gets the extra '\n'
    } while (!(answer == 'y' || answer == 'n'));

    return (answer == 'y');
}

You can check my other answer here.You will get a clear idea. the input buffer in getchar() and scanf

EDIT: As pointed out by Random832 in case of yes\n the ye is consumed but not the s\n. so a better solution is to store the first character and consume every other character until \n using a do..while or while loop. Then check the first character. Or you can store the whole string as per your need and use the first character to get the answer.

EDIT 2: flushing is not a solution to this problem. Previously I mentioned it. iharob pointed out to me that. You can check this two answers to get a clear idea.

Flushing buffers in C

How to clear input buffer in C?

Community
  • 1
  • 1
user2736738
  • 30,591
  • 5
  • 42
  • 56
  • And what if they type "yes"? Then the `s\n` is lying in wait for the next function that expects input. I would suggest using getchar in a loop until `\n` is found. Re: "flush the buffer", flushing an input buffer is rarely a good solution, and the ability to do so at all is not standard C. – Random832 May 25 '15 at 01:29
  • @iharob.: sorry! I will check the answer. We can't flush the input buffer thsi way. I just wanted it to use like a general term. – user2736738 May 25 '15 at 01:50
  • @iharob.: Just check my answer now. It's clear now. I shouldn't have mentioned it. The `fflush()` is just buffer out everything in the screen. It can be just used a s debugging. It has nothinh to do with input buffers. – user2736738 May 25 '15 at 01:53
0

To make the code robuts, i.e. for it to work with any input, you might need to read all the characters that you are not going to consider as valid, including the '\n' that is sent when you press enter and flush the input buffer, which you can't do by using fflush(), because it's only defined for output buffers, you should also consider the case of an empty line, i.e. when the user presses Enter immediately, the following code does all what I describe

#include <stdio.h>
#include <stdbool.h>

bool
adult()
{
    char answer;
    do {
        int chr;

        printf("Are you an adult? [y/n] ");
        answer = getchar();
        if (answer == '\n')
            continue;
        while (((chr = getchar()) != EOF) && (chr != '\n'));
    } while (!(answer == 'y' || answer == 'n'));

    return (answer == 'y');
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97