Home > Mobile >  Why does scanf_s() isn't working second time I am calling it in order to verify if user provide
Why does scanf_s() isn't working second time I am calling it in order to verify if user provide

Time:12-06

I am writing an application with a menu and I am asking the user to provide an integer representing an option from the menu

1. Option 1
2. Option 2
3. Option 3
...

This option is stored in a variable called

 option

I want to avoid wrong input such as "12a", "1a2", "anyString" and I've read that this can be achieved by storing return value of scanf_s() function.

So I stored it in a variable called

ret

and now I want that every time user provides wrong input to prompt them to enter a new value.

So I wrote something like this:

int ret = scanf_s("%d", &option);
while (!ret)
{
    cout << "Provide an integer, not a string! :)\n";
    ret = scanf_s("%d", &option);
}

The problem is when it enters the while it is not allowing user to enter a new value and hence the value of ret never changes, making it run endlessly.

How can I achieve what I am looking for?

CodePudding user response:

When scanf_s fails to convert an integer, the offending input stays in the input stream. Calling scanf_s("%d", &option) again will produce the same result until some characters are removed from the input stream. Note also that using scanf_s or scanf directly from stdin is error prone: the newline entered by the user stays in the input stream and will be read by a subsequent call to getchar() or fgets(), potentially causing unexpected behavior.

To avoid these pitfalls, it is recommended to read one line at a time with fgets() and convert it with sscanf() this way:

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h>

int main() {
    char buf[80];
    int option;
    char cc;

    for (;;) {
        print_menu();  // output the menu options
        if (!fgets(buf, sizeof buf, stdin)) {
            /* end of file reached: break from the loop */
            break;
        }
        /* parse exactly one integer with optional leading and trailing whitespace */
        if (sscanf(buf, "%d %c", &option, &cc) != 1) {
            printf("invalid input: %s", buf);
            printf("enter one integer exactly\n");
            continue;
        }
        printf("option is %d\n", option);
        // handle option
    }
    return 0;
}
  • Related