简体   繁体   中英

Unexpected call of printf

This is the first question I've posted about C programming on here as I just started learning C just a few weeks ago. Ill write up my code and ask what my problem is :) If Anyone please knows how I can fix my mistake or whatever I should replace for my code please reply:)!

The problem I am having, is that if you run the code for yourself, you will see that everything works fine, except for the 'else' part in the statement. The issue I am having is that when someone types more than one letter, it will run the last printf statement more than once, and will printf as many times as the user inputs a character other than y or n.

The first part with the Y or N is working fine, yet if they type any number of other chars, it doesnt just state "Please select again", one time and then re-scanf, it types out at least 2 printfs, just for even one character entered, "Please select again" "Please select again", and then, if you type more chars for the answer, it will just type even more "please select again"'s.

Please help me understand what I am doing wrong as I'm so keen on learning to program properly, but I am just stuck here atm :)

#include <stdio.h>
#include <conio.h>

int main()
{
    char answer;
    int loop = 0;

    printf("Please select. [Y/N]:\n");

    while (loop == 0)
    {
        scanf("%c", &answer);

        if (answer == 'y' || answer == 'Y')
        {
            printf("Seeyou Later Aligator.\n");
            break;
            return 0;
        }
        else if (answer == 'n' || answer == 'N')
        {
            printf("Mmkay.\n");
            break;
            return 0;
        }
        else
        {
            printf("Please select again [Y/N]:\n");
            loop = 0;
        }
    }
    getch();
    return 0;

}

scanf reads the required number of characters each time. If there are more characters, they are not ignored. They are read next time you call scanf . Hence you see multiple prints for every character. Inorder to explicitly ignore pending input, call fflush(stdin) after scanf. Which means to flush out any data in standard input stream.

Update: fflush should not be used on input streams as said in comments. Use the accepted solution for ignoring output. However I recommend using toupper or tolower instead of bit hack.

The reason as many have pointed out is that your scanf is reading the extra newline character left in the input buffer after the user presses ENTER . So here is an alternative way to read input to avoid that whole mess:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {

    char answer;
    printf("Please select. [Y/N]:\n");

    while (1)
    {

        scanf("%1s%*[^\n]", &answer);
        answer |= 0x20;

        if (answer == 'y')
        {
            puts("Seeyou Later Aligator.");
            break;
        }
        else if (answer == 'n')
        {
            puts("Mmkay.");
            break;
        }
        else
        {
            puts("Please select again [Y/N]:");
        }
    }

    getchar();
    return 0;
}

This will read just the first character found on stdin and ignore everything else after that and at the same time clear the input buffer of the newline character

  1. break; is enough ... return will never be executed as you will break out of the while
  2. Its printing more than once because scanf is taking in '\\n' and extra inputs from previous entry
  3. also the variable loop is pointless in your code

here is the fixed code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {

    char answer;

    int loop = 0;

    printf("Please select. [Y/N]:\n");

    while (1)
    {

        scanf("%c", &answer);

        if (answer == 'y' || answer == 'Y')
        {
            printf("Seeyou Later Aligator.\n");
            break;
            //return 0;
        }
        else if (answer == 'n' || answer == 'N')
        {
            printf("Mmkay.\n");
            break;
           // return 0;
        }
        else
        {
            printf("Please select again [Y/N]:\n");
            while(getchar()!='\n'){
                getchar();
                if(getchar() == '\n'){
                             break;
                }
            }

        }
    }

    getchar();
    return 0;
}

Output:

$ ./test
Please select. [Y/N]:
dddd
Please select again [Y/N]:
ffffff
Please select again [Y/N]:
y
Seeyou Later Aligator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM