crewind

Why does my code not rewind and keep the inputs in the buffer?


I made this code while I was practicing C language. But apparently this code does not rewind the input. So when I enter some data type different than int, it is upposed to go back to beginning of the while loop and start the question again. But instead of doing that, it just prints stuff infinitely. Seems like it does not rewind what`s in the buffer. I was wondering why it does that. And I use online compiler because my environment does not allow downloading Visual Studio or any compiler.

void main()
{
    char account[64];
    char password[64];
    int i, rAns;
    while (1)
    {
        printf("1.already a member? Log in\n");
        printf("2.register\n");

        if (scanf("%d", &rAns) == 0)
        {
            printf("enter right answer\n");
            rewind(stdin);
        }

        else
        {
            if (rAns < 1 || rAns > 2)
            {
                printf("enter one of the options\n");
            }
            else
            {
                break;
            }
        }
    }
}

Solution

  • Using rewind() on standard input when standard input is a terminal does nothing useful. You can't seek on a terminal. You shouldn't try using fflush(stdin) either.

    When you get 0 returned, the character that caused the failure is still in the input stream. At minimum, you need to read that character; usually, though, it is better to read the rest of the line since the user will be puzzled if you prompt them again and then process the rest of what they typed before.

    That means you need something more like:

    int main(void)
    {
        char account[64];
        char password[64];
        int i, rAns;
        while (1)
        {
            printf("1.already a member? Log in\n");
            printf("2.register\n");
    
            if (scanf("%d", &rAns) == 0)
            {
                printf("enter right answer (1 or 2)\n");
                int c;
                while ((c = getchar()) != EOF && c != '\n')
                    ;
            }
            else if (rAns < 1 || rAns > 2)
            {
                printf("enter one of the options (1 or 2)\n");
            }
            else
            {
                break;
            }
        }
        return 0;
    }
    

    You should also detect EOF on the main scanf(). That requires:

    int main(void)
    {
        char account[64];
        char password[64];
        int i, rAns;
        while (1)
        {
            printf("1.already a member? Log in\n");
            printf("2.register\n");
    
            int rc;
            if ((rc = scanf("%d", &rAns)) == EOF)
                break;
            else if (rc == 0)
            {
                printf("enter right answer (1 or 2)\n");
                int c;
                while ((c = getchar()) != EOF && c != '\n')
                    ;
            }
            else if (rAns < 1 || rAns > 2)
            {
                printf("enter one of the options (1 or 2)\n");
            }
            else
            {
                break;
            }
        }
        return 0;
    }
    

    The extra code assumes a C99 compiler which allows variables to be defined when they are needed, rather than requiring them to be defined at the start of a block. You can move the definitions to just after the preceding { if you're using an antiquated compiler.

    Warning: no code was compiled while answering this question.