开关和while组合使用scanf,如何避免多次输入

ztigrdn8  于 2023-04-11  发布在  其他
关注(0)|答案(1)|浏览(102)

在这个switchwhile的组合中,当我按'a'或'b'时,它很好,但我不希望程序在用户输入'ab'时打印12
当用户输入多个字符时,如何打印错误消息?

#include <stdio.h>

int main() {
    char move;

    while (move != 'd') {
        printf("enter a move :  ");
        scanf(" %c", &move);
        switch (move) {
            case 'a':
                printf("1\n");
                break;
            case 'b':
                printf("2\n");
                break;
            case 'c':
                printf("3 \n");
        }  // switch
    }      // while
}

样本输出:

enter a move : a
1
enter a move : b
2
enter a move : ab
1
enter a move : 2

当我输入'ab'、'ac'或'bc'或类似的值时,程序应打印错误消息。

fnx2tebb

fnx2tebb1#

我建议使用fgets来解析输入。避免常见的边缘情况会变得有些棘手,你需要处理换行符,当你按Enter键时,它也会从你的输入中解析出来,你需要清除输入以准备下一个循环,因为fgets也解析\n,你需要避免在某些情况下处理它,这里仅举几个常见的例子。
你可以这样做:
你可以在这里试试:https://onlinegdb.com/S6Uh3mrHX

#include <stdio.h>
#include <string.h>
int main() {
    char move[20] = {};
    while (move[0] != 'd') {
        printf("enter a move :  ");
        // parse and check fgets return to validate input
        if (fgets(move, sizeof move, stdin) != NULL) {
            // if we have more than 2 chars, error, fgets also parses \n and strlen counts it
            if (strlen(move) > 2) {
                printf("Error, invalid input\n");
                // if the \n character wasn't already parsed we need to handle it
                if (!strchr(move, '\n')) {
                    int c;
                    // this just clears the stdin input buffer
                    while ((c = getchar()) != '\n' && c != EOF) {}
                }
                // Since we got an error, let's reset our target buffer
                move[0] = 0;
            }
        }
        switch (move[0]) {
            case 'a':
                printf("1\n");
                break;
            case 'b':
                printf("2\n");
                break;
            case 'c':
                printf("3 \n");
        }  // switch
    }      // while
}

但是,如果您必须使用scanf,这里有一个可能的解决方案:
你可以在这里试试:https://onlinegdb.com/Hcu8dlb04G

#include <stdio.h>

int main() {
    char move = 0;  // don't forget to initialize, accessing an unitialized
                    // variable is UB (1
    while (move != 'd') {
        printf("enter a move :  ");
        if (scanf(" %c", &move) == 1) {
            int c;
            if (getchar() != '\n') {  // if more character were inputed other than newline
                printf("Error, invalid input\n");                // print error
                while ((c = getchar()) != '\n' && c != EOF) {}   // clear input buffer
                move = 0;  // reset target variable
            }
            switch (move) {
                case 'a':
                    printf("1\n");
                    break;
                case 'b':
                    printf("2\n");
                    break;
                case 'c':
                    printf("3 \n");
            }  // switch
        }      // while
    }
}

您可能还需要处理其他边缘情况,例如,假设用户输入j,没有输入错误,它只是跳到下一个输入循环(您可以在switch中处理此问题),您可能还希望添加对大写字母的支持。
1 - UB:未定义的行为,定义:https://port70.net/%7Ensz/c/c11/n1570.html#3.4.3

相关问题