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
部分并将其替换为fgets
和strtod
的组合。
检查完成:
- 输入的有效数字(通过检查由
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然后它无效,否则其有效。
我不想要精确的代码,但是我需要一些关于实现它的最佳方法的指针/线索(带有十进制的只读浮点数并拒绝整数和特殊字符)。
-
读为字符串(
fgets()
) -
保险字符串包含
'.'
,'E'
或'e'
,否则拒绝。 -
测试是否正确转换为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器以跳过初始符号。