简体   繁体   中英

C - If statement inside While loop. Continuous Scanf()

Well I want that this function returns me the change. And I have restrictions, I can't insert all types of coins. For example if I have givemeChange(0.50) I want to insert money until they are enough for pay the product. I can't find a solution. I insert 2 numbers in the terminal and then the function always go on return 0.69

This is my code:

Thank you for your time

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);
}

You run into troubles with your comparisons I guess: In the binary system, for fractions only powers of 2 can be represented exactly - 0.2 cannot be represented exactly in the binary system, because in binary, it probably will be a never ending fraction. you encounter the same in decimal with fractions like 1/3 , which is represented roughly by 0.33 , but you can never represent it exactly as decimal fraction. Thus you might have a hard time with your comparisons == . It's like (in our decimal system) 1.0 / 3.0 == 0.3333 will never be true no matter how many 3 you add at the decimal.

Instead comparing absolute values, you should resort back to checking whether your entered value is close enough to your target value like this:

...

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

  ...

However, for your problem, it would probably easier (and adivable) to read in your values as strings, then you could compare them using strcmp to the expected values and treat them appropriately, like so:

 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 */

If you also want to accept inputs like .5 or the likes, you would have to write your own compare function.

The solution is yours to pick, just for the sake of completeness, here's a tight solution that compiles straight away - went with a kind of lookup table to prevent all those if's to type...:

#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));

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM