problem in using scanf

Hello experts,
i have a small problem in getting input of variable of char type after getting input of variable of int. It does not wait for char input.
Please look at the code given below.
Thanks.


main( )
{
      char choice;
      int num1, num2, choice;    
      float ans;
      clrscr();

      printf("Pls enter two numbers  ");
      scanf("%d",&num1);
      scanf("%d", &num2);

      printf("\n*  *  * M E N U *  *   *  *\n");
      printf("\n1. Enter + to Add\n2. Enter - to Subtract \n3. Enter x to Multiply");

      printf("\n\n\tEnter Your Chioce : ");

      scanf("%c",&choice);         /* PROBLEM : DOES NOT WAIT FOR THIS */
      /* or choice=getchar();*/
      /* choice = getche(); */

      switch(choice)
      {
            case '+' :
                  ans=num1 + num2;
                  printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                  break ;

            case '-' :
                  ans=num1 - num2;
                  printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                  break ;            
      }
}
Sandeep SoodProgrammerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Infinity08Commented:
>>       scanf("%c",&choice);         /* PROBLEM : DOES NOT WAIT FOR THIS */

The scanf is reading whatever character is still on the input stream. And there is likely a newline character there (because you pressed ENTER after the previous input).

To avoid this, it's better to use fgets to read the input one line at a time into a line buffer, and then use sscanf to get whatever data you need out of that line buffer.

For example :
char line[256] = { 0 };                     /* the line buffer */

int value = 0;
fprintf(stdout, "Give an int value : ");
if (fgets(line, sizeof(line), stdin)) {
    sscanf(line, "%d", &value);
}
else {
    fprintf(stderr, "ERROR : failed reading input !");
    /* handle this error appropriately */
}

/* any reads from stdin should be replaced by something like the above */

Open in new window

phoffric\Commented:
I would replace this
      char choice;
      int num1, num2, choice;
with below since you don't want to define choice twice.
      char choice;
      int num1, num2;     

Open in new window

shajithchandranCommented:
thats because, the enter that you press after entering the num goes to c.

Try  scanf(" %c",&choice);

give a space before %c..
I am not sure if this is a std but does seem to work...

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

enggagrawalCommented:
main( )
{
      char choice;
      int  num1, num2, choice;    
      float ans;
      clrscr();

      printf("Pls  enter two numbers  ");
      scanf("%d",&num1);
      scanf("%d",  &num2);

      printf("\n*  *  * M E N U *  *   *  *\n");
      printf("\n1.  Enter + to Add\n2. Enter - to Subtract \n3. Enter x to Multiply");

      printf("\n\n\tEnter  Your Chioce : ");

      scanf("%c",&choice);         /*  PROBLEM : DOES NOT WAIT FOR THIS */
      /* or choice=getchar();*/
      /*  choice = getche(); */

      switch(choice)
      {
             case '+' :
                  ans=num1 + num2;
                   printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                   break  ;

            case '-' :
                  ans=num1 - num2;
                   printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                   break  ;            
      }
getchar(); //add this to make compiler wait
}

Sandeep SoodProgrammerAuthor Commented:
Thanks Infinity08 for your reply, but its acually very complex. Kindly suggest some simple solution.

Thanks phoffric, for your suggestion, but that was actually at typo.

Thanks shajithchandran, i am trying it.
will be back.

ashishgamre11Commented:
You have to flush the input stream. This can be done by the flushall().
Use the following code:


void main( )
{
        char choice;
        int num1, num2;
        // choice;
        float ans;
        clrscr();

        printf("Pls enter two numbers  ");
        scanf("%d",&num1);
        scanf("%d", &num2);

        printf("\n*  *  * M E N U *  *   *  *\n");
        printf("\n1. Enter + to Add\n2. Enter - to Subtract \n3. Enter x to Multiply");

        printf("\n\n\tEnter Your Chioce : ");
        flushall();//flush input stream
        scanf("%c",&choice);         /* PROBLEM : DOES NOT WAIT FOR THIS */
        /* or choice=getchar();*/
        /* choice = getche(); */

        switch(choice)
        {
                  case '+' :
                          ans=num1 + num2;
                          printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                          break ;

                  case '-' :
                          ans=num1 - num2;
                          printf("\n %d %c %d =  %f ", num1, choice, num2, ans);
                          break ;
        }
getch();//add this to make compiler wait
}
phoffric\Commented:
>> give a space before %c..
This works and allows even extra white-spaces and returns to be skipped.
Sandeep SoodProgrammerAuthor Commented:
ashishgamre11, i tried fflush() but it didnt work.
will try flushall() also.
Thanks.
Infinity08Commented:
>> Thanks Infinity08 for your reply, but its acually very complex. Kindly suggest some simple solution.

It's not really complex. If you take away the error handling (which you shouldn't in any case), you just keep :

        fgets(line, sizeof(line), stdin);
        sscanf(line, "%d", &value);

instead of this :

        scanf("%d", &value);

It's a simple matter of replacing all your scanf's with the fgets-sscanf combination.

Trust me, doing this will avoid you so many headaches, it's worth the trouble to learn to do this early.

It's a lot more robust, and avoids a lot of problems.
Infinity08Commented:
Don't use fflush on stdin (or any input stream for that matter). It has undefined behavior. Only use it for output streams.
Infinity08Commented:
flushall is non-standard, and should not be used either.
milindsmCommented:
Add getchar after scanf like this,


scanf("%c",&choice); 
getchar();

Open in new window

Sandeep SoodProgrammerAuthor Commented:
Thanks infinity for your reply.
i have tried,
Solution given by shajithchandran, i.e use one space before %c is working
and also solution given by ashishgamre11 to use flushall() is also wokring.

>> Don't use fflush on stdin (or any input stream for that matter). It has undefined behavior. Only use it for output streams

is flushall( )  safe to use ?

Thanks.
Sandeep SoodProgrammerAuthor Commented:
Infinity08,  ok, i was late in posting.
you already replied this.
Thanks.

Since shajithchandran gave a solution first, so points go to him.

I am learning many new things from you experts !
Thanks All !
Thanks Experts-Exhange !!
Infinity08Commented:
>> Solution given by shajithchandran, i.e use one space before %c is working

It works, because it skips whitespace, yes.

The approach I showed will solve that problem and several others too though (like extra input and corrupted streams eg.), so I still recommend using it over any other approach !


>> and also solution given by ashishgamre11 to use flushall() is also wokring.
>> is flushall( )  safe to use ?

It's non-standard. If you're not worrying about portability, you have to check your compiler documentation to see what its behavior is.
BUT, since this is to learn C, you should not be using it, since it's not part of the C language.


>> Since shajithchandran gave a solution first, so points go to him.

I'd say that I was first, but that doesn't matter lol ;)

I trust that at some point in the future (and probably very soon), you'll encounter more problems with reading input. I hope that at that point, you'll think of what I said, use my approach, and live happily ever after ;)

This technique is one of the most useful lessons I learned over all the years I've been using C, but it's apparently the hardest to convince people with lol. So be it.
Sandeep SoodProgrammerAuthor Commented:
Infinity08, i was looking for a very simple answer so i liked solution given by shajithchandran.
There is no doubt that the solution provided by you is better, and certainly i will try to adapt to use it.
Sorry for the points, already given.

>>This technique is one of the most useful lessons I learned over all the years I've been using C, but it's apparently the hardest to convince people with lol. So be it.

Thanks a lot for teaching the things so easily, that u learned over the years.

Hats Off !!

Thanks a lot.
Infinity08Commented:
Don't worry, thetechguy. The question has been closed just fine. Do keep the technique in mind though, because if you continue with C, you'll be happy you know it ;)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.