switch and while combination using scanf, 如何避免多重输入

问题描述 投票:0回答:1

在这个

switch
while
组合中,当我按'a'或'b'时没问题,但我不希望程序在用户输入'ab'时打印
1
2

当用户输入超过一个字符时如何打印错误消息?

#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”或类似内容时,程序应打印错误消息。

c input while-loop switch-statement buffer
1个回答
1
投票

我建议使用

fgets
来解析输入,它也是跨平台的,而且更健壮。如果你想避免常见的边缘情况,它会变得更棘手,你需要处理换行符,当你按回车键时,它也会从你的输入中解析出来,你需要清除下一个循环的输入,因为
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/VpJxEnLO0

#include <stdio.h>
#include <string.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 :  ");
        scanf(" %c", &move);
        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

© www.soinside.com 2019 - 2024. All rights reserved.