这是我第一次在这里发帖,所以这篇文章可能有点混乱,但是我会尽力解释一切。
我必须制作一个程序,其行为类似于商店中的“自助结帐”。 但是,当人们向机器中投入资金时,我遇到了两个问题。 人们像这样插入钱: 10 20 50 0.10 ....并且付款以0结束或使用ctrl + d结束。 (人们只能使用此值的硬币:如代码中所示,分别为100、50、20、10、5、2、1、0.50、0.20、0.10、0.05、0.02和0.01)
当我用0结束支付程序时,正常退出。(例如:50 20 0)
但是,当我以ctrl + d结尾时,它会导致无限循环,而我不明白为什么。
第二个问题是由于某种原因,它不会添加诸如0.10、0.20之类的数字。关于如何解决此问题或可能导致错误的任何想法?
不要介意中间的printf只是我在检查值。
float bill,x,payment=0,k=0;
printf("coins ");
while(k==0)
{
scanf("%f", &x);
if(x==0 )
{
goto END;
}
if(x ==100 || x ==50 || x ==20 || x ==10 || x ==5 || x ==2 || x ==1 || x ==0.50 || x==0.10 || x ==0.20 || x ==0.05 || x ==0.02|| x ==0.01 )
{
payment += x;
printf("==============");
printf("%.2f \n",payment);
}
else{
printf("%.2f is invalid",x);
k = 1;
goto END2;
}
}
END:
printf("%.2f \n", payment);
END2:
return 0;
答案 0 :(得分:2)
在终端中发送Ctrl+D
时,您将EOF
字符注册到stdin
,因此scanf
将不再读取任何内容,并且x
永远不会设置为0
,因此您将无法逃脱循环。
您需要检查scanf
的结果,读取man scanf
可以看到,如果成功,您期望返回值> 0。
if (scanf("%f", &x) < 1 || x = 0) // Check return value of scanf, then check x
GOTO: END;
编辑:
请注意,如果scanf
正在读取输入项目,则需要检查scanf
的返回值不小于输入项目的数量。
答案 1 :(得分:1)
根据海德和阿拉米特的评论修正此答案
您的程序“拒绝”添加小数(如0.10)的原因是因为您正在比较的变量x
和小数文字(如0.10
)具有不同的precision。
因此,要解决此问题,请将f
添加到值x == 0.10f
,或切换为使用double
并使用%lf
进行读取和打印
如果您想了解问题背后的数学原理,请阅读this。
答案 2 :(得分:1)
与浮点数进行比较时,必须小心。 0.1
的浮点表示形式在32位和64位之间不同(float
与double
)。您已将x定义为float
,并将其与0.1(即double
)进行比较。因此,比较将无法正常进行。您必须将x定义为double
,并且在代码中进行任何其他更改,或者将x == 0.1
更改为x == 0.1f
有关该主题的更多信息,请参见this answer和this topic