【问题标题】:C - If statement inside While loop. Continuous Scanf()C - While 循环内的 If 语句。连续扫描f()
【发布时间】:2018-11-25 18:52:21
【问题描述】:

我希望这个函数返回我的变化。而且我有限制,我不能插入所有类型的硬币。例如,如果我有givemeChange(0.50) 我想插入钱,直到它们足以支付产品。我找不到解决方案。我在终端中插入 2 个数字,然后函数总是继续 return 0.69

这是我的代码:

感谢您的宝贵时间

float givemeChange(float price){

printf("Only these coins are allowed:\n" );
printf("0.05€ 0.10€ 0.20€ 0.50€ 1€ 2€\n\n");

float str = 0 ;
float count = 0 ;
while(count <= price){

  printf("Insert coins\n" );
  scanf("%f\n",&str );

  if(str == 0.05){
    count = count + 0.05;
  }
  if(str == 0.10){
    count = count + 0.10;
  }
  if(str == 0.20){
    count = count + 0.20;
  }
  if(str == 0.50){
    count = count + 0.50;
  }
  if(str == 1){
    count = count + 1;
  }
  if(str == 2){
  count = count + 2;
  }
  else{
  return 0.69;
  }
 }
  return (price-count);
}

【问题讨论】:

  • 很多地方都需要else if。现在,如果str != 2,你每次返回 0.69。
  • 打印您扫描的内容,或使用您选择的其他调试方法,看看会发生什么。
  • 你可能会像往常一样遇到麻烦,你不能精确地存储任何数字,除了 2 的幂 - 你不能将 0.5 完全存储在内存中,因为在二进制系统中,它是一个永无止境的分数,比如1/3 十进制。因此,您可能很难进行比较==。就像1.0 / 3.0 == 0.3333 永远不会为真,无论您在小数点处添加多少3
  • 是的,我理解错误。现在我正在努力寻找解决方案。我为每个 if 加上 else。
  • 你的导师只要坚持“不要对这个问题使用浮点数”就可以轻松避免很多麻烦:(

标签: c if-statement while-loop floating-point scanf


【解决方案1】:

我猜你在比较时遇到了麻烦: 在二进制系统中,分数只能精确表示 2 的幂 - 0.2 不能在二进制系统中精确表示,因为在二进制中,它可能是一个永无止境的分数。 你会遇到像1/3 这样的小数的十进制相同,它大致0.33 表示,但你永远不能将它完全表示为小数。因此,您可能很难进行比较==。就像(在我们的十进制系统中)1.0 / 3.0 == 0.3333 永远不会为真,无论您在小数点后添加多少个 3。

您应该重新检查输入的值是否与目标值足够接近,而不是比较绝对值,如下所示:

...

float abs(float a) {return (a < 0) ? -a : a; }

const float epsilon = 0.005;

...

  printf("Insert coins\n" );
  scanf("%f",&str );

  if(abs(str - 0.05) < epsilon) {
      printf("Gave 0.05\n");
    count = count + 0.05;
  }

  if(abs(str - 0.10) < epsilon) {
      printf("Gave 0.10\n");
     count = count + 0.10;
  }

  ...

但是,对于您的问题,将值作为字符串读取可能会更容易(并且可以),然后您可以使用 strcmp 将它们与预期值进行比较并适当地对待它们,如下所示:

 char  input[100];

 ...

 scanf("%100s", input);
 input[99] = '\0';

 if(0 == strcmp(input, "0.05")) {
    printf("You gave 0.05\n");
    count += 0.05;
 }

 /* and so on with the other options */

如果您还想接受.5 之类的输入,则必须编写自己的比较函数。

解决方案由您选择,只是为了完整起见,这是一个可以立即编译的紧凑解决方案 - 使用一种查找表来防止所有 if's 输入...:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

float givemeChange(float price){

    struct {const char* input; float value;} input_map[] =
    {
        {"0.05", 0.05},
        {"0.10", 0.10},
        {"0.20", 0.20},
        {"0.50", 0.5}
    };

    printf("Only these coins are allowed:\n" );
    printf("0.05€ 0.10€ 0.20€ 0.50€ 1€ 2€\n\n");

    char input[100] = {0};
    float  count = 0 ;
    while(count <= price){

        printf("Insert coins\n" );
        scanf("%100s",input );
        input[99] = 0;

        for(size_t i = 0; i < sizeof(input_map) / sizeof(input_map[0]); ++i) {

            if(0 == strcmp(input_map[i].input, input)) {
                printf("Gave %s\n", input_map[i].input);
                count += input_map[i].value;
                break;
            }

        }

    }

    return count - price;
}


int main(int argc, char** argv) {

    printf("Your change %f\n", givemeChange(0.5));

}

【讨论】:

  • 是的,当然第二种方法更好。我正在努力,非常感谢你
  • 非常感谢,它就像一个魅力!经过 10 个小时的编程,我可以去睡觉了。我做了一个回显服务器,我不能做这件事,好尴尬。你是个传奇谢谢
猜你喜欢
  • 2015-08-03
  • 1970-01-01
  • 2015-05-19
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2014-01-21
  • 2015-11-08
相关资源
最近更新 更多