简体   繁体   中英

Can't clear the stdin using fflush(stdin), after using getchar(), in an infinite for loop C prog

I have just started off with C programming and while I was trying to write a programme to accept only y or n characters I came across that

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

int main()
{
  char ch;
  printf("Do you want to continue\n");

  for (;;)
    {
      ch=getchar();
      if (ch=='Y' || ch=='y')
        {
            printf("Sure!\n");
            break;
        }
        else if (ch=='N'||ch=='n')
        {
            printf("Alright! All the best!\n");
            break;
        }
        else
        {
            printf("You need to say either Yes/No\n");
            fflush(stdin);
        }

    }
    return(0);
}

When I run this code, and type in any other character other than Y/y or N/n, I receive the last printf statement (You need to say either Yes/No) as output twice. I understand that this is happening because it considers enter, ie, '\\n' as another character. Using fflush doesn't help as it's an infinite loop. How else can I modify it so that the last statement is displayed only once?

You can use a loop to read any characters left using getchar() :

  ch=getchar();
  int t;
  while ( (t=getchar())!='\n' && t!=EOF );

The type of ch should int as getchar() returns an int . You should also check if ch is EOF .

fflush(stdin) is undefined behaviour per C standard. Though, it's defined for certain platforms/compilers such as Linux and MSVC, you should avoid it in any portable code.

Another option - use scanf ignoring white spaces.

Instead of ch=getchar(); , just need scanf( " %c", &ch );

With this you can also get rid of fflush(stdin);

Like is said in my comment you should use int ch instead of char ch because the return type of getchar which is int .

To clean stdin you could do something like the following:

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

int main(void){
  int ch,cleanSTDIN;
  printf("Do you want to continue\n");

  for (;;)
    {
      ch = getchar();
      while((cleanSTDIN = getchar()) != EOF && cleanSTDIN != '\n');
      if (ch=='Y' || ch=='y')
        {
            printf("Sure!\n");
            break;
        }
        else if (ch=='N'||ch=='n')
        {
            printf("Alright! All the best!\n");
            break;
        }
        else
        {
            printf("You need to say either Yes/No\n");
        }

    }
    return(0);
}

Any way a do while will probably do the job for you:

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

int main(void){
    char ch;
    int check;

    do {
        printf("Do you want to continue: ");

        if ((scanf("%c",&ch)) == 1){
            while((check=getchar()) != EOF && check != '\n');

            if ((ch == 'y') || (ch == 'Y')){
                printf("Alright! All the best!\n");
                break;
            } else if((ch == 'n') || (ch == 'N')){
                printf("You choosed %c\n",ch);
                break;
            }else{
                printf("You need to say either Yes/No\n");
            }
        }else{
            printf("Error");
            exit(1);
        }

    }while (1);

    return 0;
}

Output1:

Do you want to continue: g
You need to say either Yes/No
Do you want to continue: y
Alright! All the best!

Output2:

Do you want to continue: n
You choosed n

Or we can simply use another break; statement after the last printf() .

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