C - trying to read a single char from stdin (and f

2019-01-08 01:01发布

as a part of a homework assignment, I'm trying to read a single char from stdin, and act according to it:

char choice;

while (1) {
    printf("please enter [y]es, [n]o or [m]aybe: ");
    scanf("%c", choice);
    fflush(stdin);
    // validate input
    if (choice == 'y' || choice == 'n' || choice == 'm') {
        break;
    } else {
      printf("Please enter only \'y\', \'n\' or \'m\'!\n");
    }
}
// do something with the input
if (choice == 'y') {
    printf("you selected yes!\n");
}

for some reason, scanf captures both the char and the line-feed after, thus it proceeds to do something with the input and then also prints the "Please enter only 'y', 'n' or 'm'!" line. If I enter several characters on the stdin, it will print that line for all of them, while also performing correctly for the first char. So, for example:

$ ./run
please enter [y]es, [n]o or [m]aybe: y<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
$ ./run
please enter [y]es, [n]o or [m]aybe: yes<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
$

Same thing happens if I use getchar. What am I missing? thanks.

标签: c scanf
4条回答
神经病院院长
2楼-- · 2019-01-08 01:33

Better still, use fgetc(). scanf() should always be a last resort.

查看更多
小情绪 Triste *
3楼-- · 2019-01-08 01:46

fflush() is not defined by ISO for input streams. It is defined in Microsoft's C runtime library, but is not portable.

While the "space before %c" solution may work when the user enters the expected data, it will fail in many ways; try entering "y n y n" for example. Console input is lin-oriented; your best bet is to ensure that you discard the entire line thus:

scanf( "%c", choice ) ;
while( choice != '\n' && getchar() != '\n' ) /* do nothing*/ ;
查看更多
在下西门庆
4楼-- · 2019-01-08 01:49

First of all I will keep it brief.Because of insufficient points to submit a comment If we can see that number of o/p is (one + the no of charcter) This is beacuse when we hit enter after entering the characters '\n' which is non-printable character also gets added after your string.

$ ./run
please enter [y]es, [n]o or [m]aybe: y<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!  -----------> it is due to reading of the '\n' by scanf

EDITED Due to insufficient points I could post this as a comment.This is a workaround of the above answers

查看更多
smile是对你的礼貌
5楼-- · 2019-01-08 01:55

You need a space between scanf(" and the %c for it to work correctly:

scanf(" %c", &choice);

And you also need to use &choice, not choice!

EDIT: While you're at it, you might want to look into do while() for that loop (unless the professor specifically said to use a break) - do while works great when validating user input!

查看更多
登录 后发表回答