-1

I'm trying to make a calculator with 12 operations, the 12th being exit, and I want it to produce an error message if the user tries to input a value other than 1-12.

I got it to work for numbers like 15, 500, etc. that aren't in the range, but if the user inputs the letter 'a' for example, it results in an infinite loop, while if the user enters 500 it does what I want it to, which is print the "try again" message and display the menu again.

So, I know the problem is with the if/else loop directly contained in the while loop, but I'm not sure why it doesn't return to the menu after the break; statement in the else statement containing "red" (I put red and blue so that I could tell which statement is being printed). I tried a do/while loop but had the same issue. I also tried making the default statement in the switch case be the "try again" part, and it works if the user enters a number like 500, but as soon as a letter or character like ? is entered, I get an infinite "try again" loop.

This is the code I'm having trouble with:

#define RESTRICT(option, min, max) (option > min && option < max)

 while(!exit) {

                    printf("Choose an option:");
                    printf("1. Eliminate.");
                    printf("2. Show fraction.");
                    printf("3. Show all fractions.");
                    printf("4. Show the absolute value.");
                    printf("5. Simplify.");
                    printf("6. Add.");
                    printf("7. Subtract.");
                    printf("8. Multiply.");
                    printf("9. Divide.");
                    printf("10. Save in archive.");
                    printf("11. Load in archive.");
                    printf("12. Exit program.");

                    if(scanf("%i", &option) == 1){
                        if(RESTRICT(option,0,12)){ 
                            switch(option){
                            case 1: 
                                printf("Example");
                                break; 
                            case 2: 
                                printf("Example");
                                break; 
                            case 3:
                                printf("Example");
                                break;               
                            case 4:
                                printf("Example");
                                break; 
                            case 5:
                                printf("Example");
                                break; 
                            case 6:
                                printf("Example");
                                break; 
                            case 7:
                                printf("Example");
                                break;                    
                            case 8:
                                printf("Example");
                                break; 
                            case 9:
                                printf("Example");
                                break; 
                            case 10:
                                printf("Example");
                                break; 
                            case 11:
                                printf("Example");
                                break; 
                            }
                        } else if (option==12){
                            printf("\nGoodbye!\n");
                            exit=1;
                        } else {
                            printf("\nThat is not an option! Try again\n");
                            printf("\nBlue\n");
                            continue;
                        }
                    } else {
                                printf("\nThat is not an option! Try again\n");
                                printf("\nRed\n");
                                break;
                        }
                    }
user438383
  • 5,716
  • 8
  • 28
  • 43

2 Answers2

1

'a' for example, it results in an infinite loop"

'a' is never consumed by if(scanf("%i", &option) == 1){. It is not numeric text, so gets put back into stdin for the next input function. Since scanf("%i", &option) if then call again, the results repeat.

Code needs to read and consume the 'a'. Consider fgets().

Best to avoid using scanf() at all until you understand why it it bad.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

According to your code, In this code scanf("%i", &option) expects interger value from the use end. when user enter non-integer value, scanf function will not store anything in the option variable. use fgets The fgets function reads a text line or a string from the specified file or console. And then stores it to the respective string variable.

Try to update your code as follows:

char input[10];
while (!exit) {
printf("Choose an option:");
printf("1. Eliminate.");
printf("2. Show fraction.");
.
.
.
  fgets(input, sizeof(input), stdin);
  if (sscanf(input, "%i", &option) == 1) {
    if (RESTRICT(option, 0, 12)) {
      switch (option) {
      case 1:
        printf("Example");
        break;
      case 2:
        printf("Example");
        break;
        .
        .
        .
      }
    } else if (option == 12) {
      printf("\nGoodbye!\n");
      exit = 1;
    } else {
      printf("\nThat is not an option! Try again\n");
      continue;
    }
  } else {
    printf("\nThat is not an option! Try again\n");
  }
}
Sachith Wickramaarachchi
  • 5,546
  • 6
  • 39
  • 68
  • If I want the user to enter a number not a character shouldn't it be int rather than char? – dinosaur2039 Dec 31 '22 at 14:49
  • yes `int option;` and you can chage code as follows `if (scanf("%i", &option) == 1) { if (RESTRICT(option, 0, 12)) { } else if (option == 12) { printf("\nGoodbye!\n"); exit = 1; } else { printf("\nThat is not an option! Try again\n"); continue; } } else { printf("\nThat is not an option! Try again\n"); }` – Sachith Wickramaarachchi Dec 31 '22 at 14:57
  • @pilarbourg what happened? – Sachith Wickramaarachchi Dec 31 '22 at 15:12
  • The fgets works but it prints "try again" first then shows the menu so im trying to solve it now, thank you :) – dinosaur2039 Dec 31 '22 at 15:23
  • For some reason the code keeps printing the else statement where it says try again first, and then it prints the menu, so it is skipping the if(RESTRICT(option, 0, 12)) and going straight to the else(try again), then moving back to the sscanf where it then asks the user for the option. Do you know why this is happening? – dinosaur2039 Dec 31 '22 at 15:53
  • @pilarbourg are you using both `scanf()` and `fgets()`? Best to avoid that like this answer (no `scanf()`). Stick to `fgets()`. – chux - Reinstate Monica Dec 31 '22 at 16:52
  • @chux-ReinstateMonica I'm using fgets() and sscanf(). Would those be ok together? I have scanf() later in the program within the switch cases, but not with fgets(). – dinosaur2039 Dec 31 '22 at 19:32
  • @pilarbourg `sscanf()` is fine. I'd recommend to not use `scnaf()` at all, but since you still want to use both `scanf()` and `fgets()` in the same program, next time you have an I/O trouble, recall what this [answer](https://stackoverflow.com/a/74970940/2410359) suggests. – chux - Reinstate Monica Dec 31 '22 at 20:23