C编码:带十进制和拒绝整数及特殊字符的只读浮点数

C编码:带十进制和拒绝整数及特殊字符的只读浮点数,c,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 n

我试图用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 = %.2f\n", floatnum);
             break;
         } 
    }
    return 0;
}
#包括
int main()
{    
双浮点数;
双depart=0.000000;
printf(“输入浮点数:”);
而(depart==0.0000000)
{
scanf(“%lf”、&floatnum);
intpart=(int)floatnum;
双depart=floatnum-intpart;
如果(depart==0.000000){
printf(“无效浮点数,请再次输入:”);
}
其他的
{
printf(“输入的数字=%.2f\n”,floatnum);
打破
} 
}
返回0;
}

我不想要精确的代码,但我需要一些关于实现这一点的最佳方法的指针/线索

如上所述,您每次输入一个字符,然后您可以在输入时计算小数和字符的数量,然后检查count_alpha>0和count_dots>1是否有效,否则无效

我重新编写了您的代码,删除了
scanf
部分,并将其替换为
fgets
strod
的组合

已完成的检查:

  • 输入的有效数字(通过检查
    strtod
    返回的endptr是否指向
    linefeed
    char,这意味着整个输入的字符串已被正确解析):避免无效数字和表单,例如
    42.4xxx
    atof
    接受
  • 如果在单个数字之后添加尾随空格,则会被换行符替换,从而被程序接受
  • 您的十进制校验码,未更改
  • 该程序允许像
    12.455e+1
    这样的数字通过(
    124.55
    ),很可能这是一个功能,而不是一个bug,因为它作为浮点有效
固定代码:

#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 = %.2f\n", floatnum);
                break;
            } 
        }
    }
    return 0;
}
我不想要精确的代码,但我需要一些指针/线索来说明实现这一点的最佳方法(带小数的只读浮点数,拒绝整数和特殊字符)

  • 读取为字符串(
    fgets()

  • 确保字符串包含
    '.
    'E'
    'E'
    ,否则拒绝

  • 测试转换为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 = %.2f\n", floatnum);
            } else {
                printf("Invalid floating point number: %s, enter again: ", buf);
            }
        }
        return 0;
    }
    
    #包括
    #包括
    int main(){
    char-buf[80];
    双浮点数;
    printf(“输入浮点数:”);
    而(扫描频率(“%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(“输入的数字=%.2f\n”,floatnum);
    }否则{
    printf(“无效的浮点数:%s,请再次输入:”,buf);
    }
    }
    返回0;
    }
    

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

    scanf()
    等将接受整数作为浮点值,
    834ww
    也可以(它最多只消耗但不包括第一个
    w
    )。这意味着您需要将输入读入字符串(可能使用
    fgets()
    ),并使用
    strod()
    函数族进行转换(使用
    strchr()
    或类似方法检查小数点等)。您的示例数据包含逗号,这令人困惑。您是在处理每行一个数字吗?对于“整数检测”,应该接受还是拒绝
    47.00
    ?它不是作为整数写入的,但值与
    47
    相同。
    4.7E39
    呢?
    -4.7E-39
    ?第一个是整数还是非整数?它是没有任何小数位数,…您测试4.7E39的代码有缺陷;您得到了未定义的行为,因为该值太大,无法放入整数。定义
    47.00
    被拒绝肯定会让生活更艰难;这意味着3.14159E5被拒绝,但3.141593E5不是。1)拒绝
    “47.00”
    是与“只接受带小数的浮点数”。2)您的代码拒绝
    0.99999999999999999999:
    ,因为它将带舍入的字符串转换为
    1
    。“它是整数吗”主题的另一个变体:
    47.000000000000000000000000000001
    (25个零,除非我在键入时计算错误,尽管数字足够大(比如说超过20个),有多少并不重要)。转换为
    double
    后,您将很难检测它与
    47
    之间的差异。如果用户键入abc.def,如何处理?取3个变量,一个表示位数,第二个表示点,第三个表示任何其他字符。输入时,如果是数字,则计算数字++,如果是点,则点++,否则变量+,然后使用if(count\u dig>0&&count\u dot==1&&count\u other==0)然后有效,否则无效。让我也这样试试。我想如果你有任何问题的话,应该可以让我知道。谢谢。我会用我的大脑来固定尾随空格。我会尝试。像
    45.0
    这样的输入不应该被接受吗?这个答案会拒绝。注意
    char buf[100]
    的定义,然后使用
    fg
    
    #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 = %.2f\n", floatnum);
            } else {
                printf("Invalid floating point number: %s, enter again: ", buf);
            }
        }
        return 0;
    }