C

C 知识量:16 - 74 - 317

8.2 缓冲输入问题><

解决缓冲输入问题- 8.2.1 -

缓冲输入用起来比较方便,因为在把输入发送给程序之前,用户可以编辑输入。但有时,这种输入方式也会带来麻烦。以下是一个猜数字程序:

#include <stdio.h>

int main(void) {
    int guess = 1;
    printf("Pick an integer from 1 to 100.I will try to guess it.\n"
            "Respond with a y if my guess is right and with\n"
            "an n if it is wrong.\n");
    printf("Uh...is your number %d?\n", guess);
    while (getchar() != 'y')
        printf("Well,then,is it %d?\n", ++guess);
    printf("I knew I could do it!\n");
    system("pause");
    return 0;
}

运行的结果类似于:

Pick an integer from 1 to 100.I will try to guess it.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well,then,is it 2?
Well,then,is it 3?
n
Well,then,is it 4?
Well,then,is it 5?
y
I knew I could do it!

从以上结果看,代码的最大问题是,每次输入n时,程序会打印两条消息。这是因为当输入n并按下Enter键后,n和换行符(Enter键的效果)都作为输入进入了while循环,而getchar()连续读取了n和换行符,导致连续打印了两条消息。

对于以上问题,一种解决方案是,使用while循环丢弃输入行最后剩余的内容,包括换行符,这样,即使输入的是no或no way等字符串,程序也可以视为n。修改后的while部分如下:

while (getchar() != 'y') {
    printf("Well,then,is it %d?\n", ++guess);
    while (getchar() != '\n')
        continue;
}

再运行后,结果将类似于:

Pick an integer from 1 to 100.I will try to guess it.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well,then,is it 2?
no
Well,then,is it 3?
no way
Well,then,is it 4?
y
I knew I could do it!

修改后的代码解决了换行符导致的重复打印问题。还有一个问题就是,对于forget it等不是以n开头表示猜错意思的输入,程序仍会视为n。可以通过添加一个if语句用于筛选其他响应来解决。修改后的代码:

#include <stdio.h>

int main(void) {
    int guess = 1;
    char response;
    printf("Pick an integer from 1 to 100.I will try to guess it.\n"
            "Respond with a y if my guess is right and with\n"
            "an n if it is wrong.\n");
    printf("Uh...is your number %d?\n", guess);
    while ((response = getchar()) != 'y') {
        if (response == 'n')
            printf("Well,then,is it %d?\n", ++guess);
        else
            printf("Sorry,I understand only y or n.\n");
        while (getchar() != '\n')
            continue;
    }
    printf("I knew I could do it!\n");
    system("pause");
    return 0;
}

运行后,结果将类似于:

Pick an integer from 1 to 100.I will try to guess it.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well,then,is it 2?
no
Well,then,is it 3?
no way
Well,then,is it 4?
forget it
Sorry,I understand only y or n.
n
Well,then,is it 5?
ok
Sorry,I understand only y or n.
y
I knew I could do it!