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

我试图用C(gcc)编写一个代码,只接受带小数的浮点数,并拒绝整数,特殊字符,字母数字输入。

有效条目是:

1.23, 3.45, 6.77 

无效的条目:

 abc, e34, 834ww, 6, 9, 

还有一些不是浮动的事情。 这是我尝试过的:

 #include  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; } 

我不想要确切的代码,但我需要一些关于什么是实现这一目标的最佳方法的指针/线索。

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

检查完成:

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

固定代码:

 #include  #include  #include  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; } 

测试:

 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. 测试是否正确转换为FP而没有尾随垃圾。 ( strtod()sscanf("%lf %n",... )并且是有限的( isfinite()

规范是模糊的:你是否打算接受0.00作为带小数的浮点值,尽管它恰好有一个整数值?

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

这是一个替代方法,它接受带小数点前后数字的正数:

 #include  #include  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; } 

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