C编码:只读带小数的浮点数,拒绝整数和特殊字符



我试图用C (gcc)编写代码,只接受带有小数的浮点数,拒绝整数,特殊字符,字母数字条目。

有效条目有:

1.23, 3.45, 6.77

无效的条目:

abc, e34, 834ww, 6, 9,

和一些不是浮点数的东西。这是我尝试过的:

#include <stdio.h>
int main()
{    
    double floatnum;
    double decpart=0.000000;
    printf("Enter a floating number num: ");
    while (decpart == 0.0000000)
    {
         scanf("%lf", &floatnum);
         int intpart = (int)floatnum;
         double decpart = floatnum - intpart;
         if (decpart == 0.000000){
             printf("Invalid floating point number, enter again: ");
         }
         else
         {
             printf("Number entered = %.2fn", floatnum);
             break;
         } 
    }
    return 0;
}

我不想要确切的代码,但我需要一些指针/线索,什么是最好的方式来实现这一点。

我重新编写了您的代码,删除了scanf部分,并用fgetsstrtod的组合代替它。

:检查

  • 输入的有效数字(通过检查strtod返回的endptr是否指向linefeed字符,这意味着整个输入的字符串已被正确解析):避免无效数字和atof接受的42.4xxxx形式,例如
  • 如果在单个数字后面添加尾随空格,则将其替换为换行,从而被程序接受
  • 您的十进制校验码,未更改
  • 程序允许像12.455e+1这样的数字通过(124.55),好吧,也许这是一个特性而不是一个错误,因为它作为浮点数是有效的。
固定代码:

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
int main()
{
    double decpart;
    printf("Enter a floating number num: ");
    char buf[100];
    int len;
    char *endptr;
    while (fgets(buf,sizeof(buf),stdin) != NULL)
    {
        len = strlen(buf)-1;
        // right strip spaces (replace by linefeed like fgets ends the input)
        while (len>0)
        {
            len--;
            if (buf[len]==' ')
            {
                buf[len]='n';
            }
            else
            {
                break;
            }
        }
        double floatnum = strtod(buf,&endptr);
        if ((endptr==buf)||(endptr[0]!='n'))
        {
            printf("Invalid floating point number, enter again: ");
        }
        else
        {
            int intpart = (int)floatnum;
            double decpart = floatnum - intpart;
            if (decpart == 0.000000){
                printf("Invalid floating point number, enter again: ");
            }
            else
            {
                printf("Number entered = %.2fn", floatnum);
                break;
            } 
        }
    }
    return 0;
}

测试:

Enter a floating number num: no
Invalid floating point number, enter again: 45
Invalid floating point number, enter again: 45.6xxx
Invalid floating point number, enter again: 45.6
Number entered = 45.60

正如你上面评论的那样,你每次输入一个字符,那么你可以在输入时计算小数和字符的数量,然后检查count_alpha>0和count_dots>1,那么它无效,否则它有效。

我不想要精确的代码,但我需要一些指针/线索来实现这一点的最佳方法(只读带十进制的浮点数,拒绝整数和特殊字符)。

  1. 读取为字符串(fgets())

  2. 确保字符串包含'.''E''e',否则拒绝。

  3. 测试if是否正确转换为FP,没有尾随垃圾。(strtod()sscanf("%lf %n",...)并且是有限的(isfinite())

规范是模棱两可的:您打算接受0.00作为带有小数的浮点值,尽管它恰好具有整数值?

你的实现会拒绝它,但是它会接受不符合标准的1e-1

这里是另一种接受数字在小数点前后的正数的方法:

#include <stdio.h>
#include <string.h>
int main() {    
    char buf[80];
    double floatnum;
    printf("Enter floating point numbers: ");
    while (scanf("%79s", buf) == 1) {
        int len = strlen(buf);
        int pos = -1;
        sscanf(buf, "%*[0-9].%*[0-9]%n", &pos);
        if (pos == len && sscanf(buf, "%lf", &floatnum) == 1) {
            printf("Number entered = %.2fn", floatnum);
        } else {
            printf("Invalid floating point number: %s, enter again: ", buf);
        }
    }
    return 0;
}

如果您也希望接受负数和带有冗余正号的数字,您可以扩展验证器以跳过初始符号。

最新更新