0

I was at first having trouble with a scanf() function being skipped, but I fixed that by adding in a space before %c in the scanf() function.

When trying to ask for input from the user as to whether the screen should be cleared, the scanf(" %c", cClear); conversion specifier gives an infinite loop, it is expecting a character, but responds to input as if not a character.

I believe it may have something to do with my input buffer.

I tried to use fflush(stdin) to no avail, I also used printf("%d", (int) cClear); to see the output, which was zero.

One other problem I have is trying to check user input for a digit.

I use:

if (isdigit(iSelection) == 0) {
            printf("\nPlease select a valid numerical value.\n");
            continue;

to check user input and restart the while loop, but anytime a character is entered and not an integer, I get an infinite loop.

My goal is to give the user the option to clear the screen after each calculation, and to also check input for being a digit.

Any help is appreciated.

//excluding code prior to main() and function definitions

int main(void) {
    int iSelection = -1;
    double foperand1 = 0, foperand2 = 0;
    int ioperand1 = 0, ioperand2 = 0;
    char cClear = '\0';
    
    while (iSelection) {
    
        printf("\n\nTHE CALCULATOR\n");
        printf("\nCalculator menu:\n");
        printf("\n1\tAddition");
        printf("\n2\tSubtraction");
        printf("\n3\tMultiplication");
        printf("\n4\tDivision");
        printf("\n5\tModulus (Integers only)");
        printf("\n6\tTest if Prime (Integers only)");
        printf("\n7\tFactorial (Integers only)");
        printf("\n8\tPower");
        printf("\n9\tSquare Root");
        printf("\n0\tExit\n");
        printf("\nPlease enter your selection: ");
        scanf("%d", &iSelection);   
        
        //here we check for if input was a digit
        if (isdigit(iSelection) == 0) {
            printf("\nPlease select a valid numerical value.\n");
            continue;
        
    
        switch(iSelection) {
            case 0:
                break;
                
            case 1:
                printf("\nEnter the two numbers to add seperated by a space: ");
                scanf("%lf %lf", &foperand1, &foperand2);
                printf("\n%.5lf + %.5lf = %.5lf\n", foperand1, foperand2, addNumbers(foperand1, foperand2));    
                break;
                
            
        }
        //here we ask the user if they want to clear the screen
        fflush(stdin)
        if (iSelection != 0) {
            printf("\nDo you want to clear the screen? ('y' or 'n'): ");
            scanf("%c", cClear);
            //printf("%d", (int) cClear);    //used this to help debug
            //scanf("%d", iSelection);
            if (cClear == 'y')
                system("cls");
        }
    }
    printf("\nExiting\n");
    return 0;
}

one error I get is "system" is declared implicitely. Could it possibly be the windows operating system not recognizing the pre defined function call?

  • 1
    isdigit() checks for a decimal digit character. You are passing it an integer. Also, for the scanf() call you want to pass &cClear. – jmq Oct 28 '22 at 20:16
  • 1
    If you get an error that mentions "declared implicity", you need to read the documentation for the function and find out which header file to `#include`. – user3386109 Oct 28 '22 at 20:19
  • With those arguments to `scanf`, `iSelection` will always be a digit - you've declared it as an integer... can't be anything else. Check the return value of `scanf` to know if the parse was successful – fredrik Oct 28 '22 at 20:20
  • Please fix a [mre] when you create a question – klutt Oct 28 '22 at 20:27
  • 1
    @fredrik *With those arguments to `scanf`, `iSelection` will always be a digit* No it won't. Given `scanf("%d", &iSelection);`, if the user enters `ASDF`, `iSelection` will remain `-1` which isn't a digit per `isdigit()`, the `ASDF` will remain in the input buffer, and the code will infinite loop as `scanf()` tries and fails to read the same `ASDF` over and over. **This is why you ALWAYS check the return value from `scanf()`**. – Andrew Henle Oct 28 '22 at 20:53
  • You didn't use %c. You used %d. – user253751 Oct 28 '22 at 21:16
  • 1
    OT: Before you write a `main()` that is 300 lines of code, consider writing (and testing) a separate function for each of the operations to be performed. Break things down into individual servings and don't mash everything together into a single impenetrable mash-up... – Fe2O3 Oct 29 '22 at 00:43
  • You do know, your entire menu can be output with a single call to `fputs()` (or a single `printf()`)? – David C. Rankin Oct 29 '22 at 02:42
  • See [Menu with single fputs()](https://paste.opensuse.org/40284166) – David C. Rankin Oct 29 '22 at 02:48

1 Answers1

1

Thanks to the people who commented to help me figure this out.

I had forgotten to add the (&) to the scanf() function call for the system"cls" function call, as well as didn't include the correct library (stdlib.h).

I was also able to make the program stop skipping the scanf() function by adding a space to the " %c" conversion specifier. scanf Getting Skipped

I was able to make the isdigit() function work by changing the variable 'iSelection' to a character, but then I also had to change my case values to characters, not integers.

  • Q: Are you checking the return value from "scanf()"? Q: Would you considered using "fgets()" to read the line, and "sscanf()" to parse the value(s)? `if (isdigit(iSelection) == 0)` smells like it could be a bug. Q: Have you tried entering "XXX" (instead of a valid digit)? – paulsm4 Oct 29 '22 at 00:34