C中的输入验证

时间:2012-10-21 13:30:03

标签: c input validation

我正在用C语言编写程序。在程序中,用户必须选择一个数字,1,2或3.我想构造代码,以便当用户输入的数字不是' t 1,2或3,他/她将被告知“无效选择 - 再次选择”,然后他们将被带回到程序的开头:

int main() {

    int choice;
    char response, Y, N;

    printf("Choose a shape from the following:\n 1.Sphere\n 2.Cone\n 3.Cylinder\n");

    scanf("%d",&choice);

    if(choice==1||choice==2||choice==3) {
        printf("Enter the radius, r\n");                             
    } else
        printf("Invalid selection, choose again.\n");

}

我想要的是,在“无效选择,再次选择”出现后,用户返回到程序的开头,这样他们就可以再次输入他们的选择。我该怎么做?

5 个答案:

答案 0 :(得分:1)

为此

使用while循环
int main()
{
    int choice;
    char response, Y, N;

    printf("Choose a shape from the following:\n 1.Sphere\n 2.Cone\n 3.Cylinder\n");
    while(1)
    {
        scanf("%d",&choice);

        if(choice==1||choice==2||choice==3)
        {
            printf("Enter the radius, r\n");                             
            //Maybe read the radius here
            scanf("%d",&radius);
            break;
        }
        else
            printf("Invalid selection, choose again.\n");
    }
}

答案 1 :(得分:1)

以下是您的工作:

int choice;
char response, Y, N;
for (;;) {
    printf("Choose a shape from the following:\n 1.Sphere\n 2.Cone\n 3.Cylinder\n");

    scanf("%d",&choice);

    if(choice==1||choice==2||choice==3) {
        break;                    
    }
    printf("Invalid selection, choose again.\n");
}

此循环结束后,提示半径。你几乎肯定需要另一个循环来防止输入半径的负值,所以不要在同一个循环中提示它。

答案 2 :(得分:0)

使用do-while循环,循环直到输入正确为止 这样做,为退出添加选项4:

 do {
        scanf("%d",&choice);
int flag=0;
        if(choice==1||choice==2||choice==3) {
            printf("Enter the radius, r\n");                             
        } else {
            printf("Invalid selection, choose again.\n");
            flag=1;
        }
    } while(flag==1&& choice!=4);

答案 3 :(得分:0)

有些人会反对这一点,但我认为在这些情况下,一个普通的goto是一种非常干净和可读的做事方式,因为它强调了“正常”控制路径的线性:

int main(int arg, char *argv[])
{
    int choice;

choose_shape:
    printf("Choose a shape from the following:\n"
           " 1.Sphere\n 2.Cone\n 3.Cylinder\n");
    scanf("%d", &choice);
    if (choice < 1 || choice > 3) {
        printf("Invalid selection, please choose again.\n");
        goto choose_shape;
    }

    printf("Enter the radius, r:\n");
    ...
}

是的,人们抱怨goto所以让我再说一遍。

这是一个更复杂的版本,允许您通过字母选择形状:

    char c;
    shape_t shape;
choose_shape:
    printf("Choose a shape: [s]phere, [c]one, c[y]linder:\n");
    scanf("%c", &c);
    switch (c) {
    cases 's':
        shape = SHAPE_SPHERE;
        break;

    case 'c':
        shape = SHAPE_CONE;
        break;

    case 'y':
        shape = SHAPE_CYLINDER;
        break;

    default:
        printf("Not a valid shape: %c\n", c);
        goto choose_shape;
    }

这是goto的版本。请注意,这引入了另一个变量flag,其唯一目的是去除goto语句。由于break语句,您不能在此处使用goto(这是一个未标记的switch)。由于附加状态,我认为这更难阅读。它的行数要长五行。

    char c;
    shape_t shape;
    int flag;
    for (flag = 0; !flag; ) {
        printf("Choose a shape: [s]phere, [c]one, c[y]linder:\n");
        scanf("%c", &c);
        switch (c) {
        cases 's':
            shape = SHAPE_SPHERE;
            flag = 1;
            break;

        case 'c':
            shape = SHAPE_CONE;
            flag = 1;
            break;

        case 'y':
            shape = SHAPE_CYLINDER;
            flag = 1;
            break;

        default:
            printf("Not a valid shape: %c\n", c);
            break;
        }
    }

答案 4 :(得分:0)

这是您可以考虑的替代方案。请注意,获取用户输入被分成一个函数,main()只调用该函数并在出错时循环。 main()的读者可能并不关心你如何获得输入选择,那么为什么要让他们阅读呢?

另请注意,我使用的是fgets,而不是scanf。如果使用scanf运行版本并输入非数字,则该字符将无限期地保留在输入缓冲区中; scanf永远不会删除它,因为它正在寻找满足%d格式字符串的数字 - 因此是一个无限循环。您可以尝试在stdin之前刷新scanf(使用fpurge),但该函数仍然无法正确处理stdin的关闭(例如,在shell UNIX上使用ctrl-d)基于系统)。

#include <stdio.h>
#include <stdlib.h>

static int get_shape(int *shape)
{
    char buf[10] = "";
    printf("Choose a shape from the following:\n"
           " 1.Sphere\n 2.Cone\n 3.Cylinder\n");

    if (!fgets(buf, sizeof buf, stdin)) { /* Note: fgets, not scanf */
        exit(1); /* ctrl-d */
    }
    *shape = strtol(buf, NULL, 0);

    if (*shape==1 || *shape==2 || *shape==3) {
        return 1;
    }
    printf("Invalid selection\n");
    return 0;
}

int main(int argc, char ** argv)
{
    int shape = 0;
    while (!get_shape(&shape)) {
        /* loop */
    }
    printf("Choice: %d\n", shape);
    return 0;
}