当前位置:   article > 正文

mfc 固定编辑框输入上限和下限_C语言输入验证的3种方法

mfc不满足输入范围后处理
2551133ebade41f6c3667a7ee9a6373e.png

在实际应用中,用户不一定会按照程序的指令行事。
用户的输入和程序期望的输入不匹配时常发生,这会导致程序运行失败。作为程序员,除了完成编程的本职工作,还要事先预料一些可能的输入错误,这样才能编写出能检测并处理这些问题的程序。例如,假设我们编写了一个处理非负数整数的循环,但是用户很可能输入一个负数。
你可以使用关系表达式来排除这种情况:

long n;scanf("%ld", &n);      // get first valuewhile (n >= 0)        // detect out-of-range value{    // process n    scanf("%ld", &n);  // get next value}

另一类潜在的陷阱是,用户可能输入错误类型的值,如字符q。排除这种情况的一种方法是,检查scanf()的返回值。回忆一下,scanf()返回成功读取项的个数。因此,下面的表达式当且仅当用户输入一个整数时才为真:

scanf("%ld", &n) == 1

结合上面的while循环,可改进为:

long n;while (scanf("%ld", &n) == 1 && n >= 0){    // process n}

while循环条件可以描述为“当输入是一个整数且该整数为正时”。

对于最后的例子,当用户输入错误类型的值时,程序结束。
然而,也可以让程序友好些,提示用户再次输入正确类型的值。在这种情况下,要处理有问题的输入。如果scanf()没有成功读取,就会将其留在输入队列中。这里要明确,输入实际上是字符流。可以使用getchar()函数逐字符地读取输入,甚至可以把这些想法都结合在一个函数中,如下所示:

long get_long(void){    long input;    char ch;    while (scanf("%ld", &input) != 1)    {        while ((ch = getchar()) != '')            putchar(ch);  // dispose of bad input        printf(" is not an integer.nPlease enter an ");        printf("integer value, such as 25, -178, or 3: ");    }    return input;}

该函数要把一个long类型的值读入变量input中。如果读取失败,函数则进入外层while循环体。然后内层循环逐字符地读取错误的输入。注意,该函数丢弃该输入行的所有剩余内容。还有一个方法是,只丢弃下一个字符或单词,然后该函数提示用户再次输入。外层循环重复运行,直到用户成功输入整数,此时scanf()的返回值为1。

在用户输入整数后,程序可以检查该值是否有效。考虑一个例子,要求用户输入一个上限和一个下限来定义值的范围。在该例中,你可能希望程序检查第1个值是否大于第2个值(通常假设第1个值是较小的那个值),除此之外还要检查这些值是否在允许的范围内。例如,当前的档案查找一般不会接受1949年以前和2020年以后的查询任务。这个限制可以在一个函数中实现。

假设程序中包含了stdbool.h头文件。如果当前系统不允许使用_Bool,把bool替换成int,把true替换成1,把false替换成0即可。注意,如果输入无效,该函数返回true,所以函数名为bad_limits():

bool bad_limits(long begin, long end,                long low, long high){    bool not_good = false;    if (begin > end)    {        printf("%ld isn't smaller than %ld.", begin, end);        not_good = true;    }    if (begin < low || end < low)    {        printf("Values must be %ld or greater.", low);        not_good = true;    }    if (begin > high || end > high)    {        printf("Values must be %ld or less.", high);        not_good = true;    }    return not_good;}

下面的程序清单8使用了上面的两个函数为一个进行算术运算的函数提供整数,该函数计算特定范围内所有整数的平方和。程序限制了范围的上限是10000000,下限是-10000000。

Listing 8.7 The checking.c Program

// checking.c -- validating input#include #include // validate that input is an integerlong get_long(void);// validate that range limits are validbool bad_limits(long begin, long end,                long low, long high);// calculate the sum of the squares of the integers// a through bdouble sum_squares(long a, long b);int main(void){    const long MIN = -10000000L;  // lower limit to range    const long MAX = +10000000L;  // upper limit to range    long start;                   // start of range    long stop;                    // end of range    double answer;    printf("This program computes the sum of the squares of "           "integers in a range.nThe lower bound should not "           "be less than -10000000 andnthe upper bound "           "should not be more than +10000000.nEnter the "           "limits (enter 0 for both limits to quit):n"           "lower limit: ");    start = get_long();    printf("upper limit: ");    stop = get_long();    while (start !=0 || stop != 0)    {        if (bad_limits(start, stop, MIN, MAX))            printf("Please try again.n");        else        {            answer = sum_squares(start, stop);            printf("The sum of the squares of the integers ");            printf("from %ld to %ld is %gn",                    start, stop, answer);        }        printf("Enter the limits (enter 0 for both "               "limits to quit):n");        printf("lower limit: ");        start = get_long();        printf("upper limit: ");        stop = get_long();    }    printf("Done.n");    return 0;}long get_long(void){    long input;    char ch;    while (scanf("%ld", &input) != 1)    {        while ((ch = getchar()) != 'n')            putchar(ch);  // dispose of bad input        printf(" is not an integer.nPlease enter an ");        printf("integer value, such as 25, -178, or 3: ");    }    return input;}double sum_squares(long a, long b){    double total = 0;    long i;    for (i = a; i <= b; i++)        total += (double)i * (double)i;    return total;}bool bad_limits(long begin, long end,                long low, long high){    bool not_good = false;    if (begin > end)    {        printf("%ld isn't smaller than %ld.n", begin, end);        not_good = true;    }    if (begin < low || end < low)    {        printf("Values must be %ld or greater.n", low);        not_good = true;    }    if (begin > high || end > high)    {        printf("Values must be %ld or less.n", high);        not_good = true;    }    return not_good;}

下面是该程序的输出示例:

This program computes the sum of the squares of integers in a range.

The lower bound should not be less than -10000000 and

the upper bound should not be more than +10000000.

Enter the limits (enter 0 for both limits to quit):

lower limit: low

low is not an integer.

Please enter an integer value, such as 25, -178, or 3: 3

upper limit: a big number

a big number is not an integer.

Please enter an integer value, such as 25, -178, or 3: 12

The sum of the squares of the integers from 3 to 12 is 645

Enter the limits (enter 0 for both limits to quit):

lower limit: 80

upper limit: 10

80 isn't smaller than 10.

Please try again.

Enter the limits (enter 0 for both limits to quit):

lower limit: 0

upper limit: 0

Done.

1 分析程序

虽然checking.c程序的核心计算部分(sum_squares()函数)很短,但是输入验证部分比以往程序示例要复杂。接下来分析其中的一些要素,先着重讨论程序的整体结构。

程序遵循模块化的编程思想,使用独立函数(模块)来验证输入和管理显示。程序越大,使用模块化编程就越重要。

main()函数管理程序流,为其他函数委派任务。它使用get_long()获取值、while循环处理值、bad_limits()函数检查值是否有效、sum_squres()函数处理实际的计算:

start = get_long();printf("upper limit: ");stop = get_long();while (start !=0 || stop != 0){    if (bad_limits(start, stop, MIN, MAX))        printf("Please try again.n");    else    {        answer = sum_squares(start, stop);        printf("The sum of the squares of the integers ");        printf("from %ld to %ld is %gn", start, stop, answer);    }    printf("Enter the limits (enter 0 for both "           "limits to quit):n");    printf("lower limit: ");    start = get_long();    printf("upper limit: ");    stop = get_long();}

2 输入流和数字

在编写处理错误输入的代码时,应该很清楚C是如何处理输入的。考虑下面的输入:

is  28 12.4

在我们眼中,这就像是一个由字符、整数和浮点数组成的字符串。但是对C程序而言,这是一个字节流。第1个字节是字母i的字符编码,第2个字节是字母s的字符编码,第3个字节是空格字符的字符编码,第4个字节是数字2的字符编码,等等。所以,如果get_long()函数处理这一行输入,第1个字符是非数字,那么整行输入都会被丢弃,包括其中的数字,因为这些数字只是该输入行中的其他字符:

while ((ch = getchar()) != 'n')   ptchar(ch);  // dispose of bad input

虽然输入流由字符组成,但是也可以设置scanf()函数把它们转换成数值。例如,考虑下面的输入:

: 42

如果在scanf()函数中使用%c转换说明,它只会读取字符4并将其存储在char类型的变量中。
如果使用%s转换说明,它会读取字符4和字符2这两个字符,并将其存储在字符数组中。
如果使用%d转换说明,scanf()同样会读取两个字符,但是随后会计算出它们对应的整数值:4×10+2,即42,然后将表示该整数的二进制数存储在int类型的变量中。
如果使用%f转换说明,scanf()也会读取两个字符,计算出它们对应的数值42.0,用内部的浮点表示法表示该值,并将结果存储在float类型的变量中。

简而言之,输入由字符组成,但是scanf()可以把输入转换成整数值或浮点数值。使用转换说明(如%d或%f)限制了可接受输入的字符类型,而getchar()和使用%c的scanf()接受所有的字符。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/83020
推荐阅读
相关标签
  

闽ICP备14008679号