Why does scanf_s() isn't working second time I am calling it in order to verify if user provided correct input?

Why does scanf_s() isn't working second time I am calling it in order to verify if user provided correct input?

Problem Description:

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?

Solution – 1

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 exactlyn");
            continue;
        }
        printf("option is %dn", option);
        // handle option
    }
    return 0;
}
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject