我试图用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
部分,并用fgets
和strtod
的组合代替它。
- 输入的有效数字(通过检查
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,那么它无效,否则它有效。
我不想要精确的代码,但我需要一些指针/线索来实现这一点的最佳方法(只读带十进制的浮点数,拒绝整数和特殊字符)。
-
读取为字符串(
fgets()
) -
确保字符串包含
'.'
、'E'
或'e'
,否则拒绝。 -
测试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;
}
如果您也希望接受负数和带有冗余正号的数字,您可以扩展验证器以跳过初始符号。