Buffer cleaning after getchar

Good Morning,

Wanted to know how I can optimize the buffer cleaning by using the function getchar (), as an example follow the following codes:

I get the following code to have the correct output using the "spacing in scanf as shown:

#include <stdio.h>

int main()
{
 float salario, imposto = 0.0;
 char sexo;

 printf ("Introduza o Salário: ");
 scanf("%f",&salario);
 printf ("Introduza o sexo: ");
 scanf (" %c",&sexo);
 switch (sexo)
   {
     case 'f':
     case 'F': imposto = 0.10;
             break;
     case 'm':
     case 'M': imposto = 0.05;
              break;
   }

   printf("Imposto %.2f\n",salario*imposto);

   return 0;
}

However I cannot execute the following code correctly:

#include <stdio.h>

int main()
{
 float salario, imposto = 0.0;
 char sexo;

 printf ("Introduza o Salário: ");
 scanf("%f",&salario);
 printf ("Introduza o sexo: ");
 sexo = getchar();
 switch (sexo)
   {
     case 'f':
     case 'F': imposto = 0.10;
             break;
     case 'm':
     case 'M': imposto = 0.05;
              break;
   }

   printf("Imposto %.2f\n",salario*imposto);

   return 0;
}

Showing the following output without letting me enter the gender:

Enter salary: 100 enter gender: tax 0.00

Thanks for the help.

 3
Author: Gonkali, 2014-12-11

4 answers

getchar() not a good option to read user input. The reason behind this is that the function will return only the first character of the input buffer (or keyboard buffer).

Let's look at an example: if you press key and and then key Enter on the keyboard, the buffer would store:

 ------------------------------------
| 'E' | '\n' |     |     |     |     |
 ------------------------------------

At this point, when executing the code below, the function getchar() consumes only the first element of the buffer, leaving the rest intact:

printf ("Introduza o sexo: ");
sexo = getchar();

See how the keyboard buffer would look after the function getchar() is executed:

 ------------------------------------
| '\n' |     |     |     |     |     |
 ------------------------------------

The problem is that if your program ran the getchar() function again, and the user pressed any other key (like F , for example), the new data would be entered at the end of the buffer:

 ------------------------------------
| '\n' | 'F' |     |     |     |     |
 ------------------------------------

Thus, the next execution of getchar() would return \n instead of F , and you would be under the impression that your program does not work.

In this way , it is extremely necessary to clear the input buffer after running getchar() so that it does not over anything in the buffer. That's why the answer of @mutley is important. Some people may still recommend running the function fflush(stdin) after getchar() but this is highly inappropriate because fflush() serves only to clear an output stream. Using it in an input stream like stdin causes undefined behavior behavior).

As an alternative, it is recommended to use fgets() with stdin.

 3
Author: karlphillip, 2014-12-12 12:59:12

You can use the following line, along with the includes of the Code:

#DEFINE flush "while ( getchar() != '\n' );"

With the code going like this:

#include <stdio.h>
#DEFINE flush "while ( getchar() != '\n' );"

int main()
{
  float salario, imposto = 0.0;
  char sexo;

  printf ("Introduza o Salário: ");
  scanf("%f",&salario);
  printf ("Introduza o sexo: ");
  flush;
  sexo = getchar();
  switch (sexo)
  {
    case 'f':
    case 'F': imposto = 0.10;
              break;
    case 'm':
    case 'M': imposto = 0.05;
              break;
  }

 printf("Imposto %.2f\n",salario*imposto);

 return 0;
}

And although I didn't read it, the source of my answer suggested you read this link, this link and more this link .

Source

 3
Author: mutlei, 2017-05-23 12:37:28

The function I use is similar to the one user mutlei suggested.

void limpaBuffer(void){
    char c;
    while((c = getchar()) != '\n' && c != EOF);
}

The difference is that in this case it can be used in a file that has to be cleaned to the end, and not only when the condition is '\n'.

But I believe it is better to apply a function of its own, since native solutions, fflush(), __fpurge() they are dependent on Windows and Linux platforms, respectively. And this can cause problems if you are not absolutely sure where your program will run.

 1
Author: pmargreff, 2017-04-13 12:59:39

Just insert the \n at the end of reading the number that it will not stay in the input buffer:

scanf("%f\n",&salario);
scanf ("%c",&sexo);
 0
Author: vmp, 2014-12-15 04:43:14