Buffer Cleanup after getchar

3

Good morning,

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

I get the following code from the correct output using the "scanf spacing" technique 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 can not correctly run the following code:

#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;
}

Presenting the following output without letting me enter the sex:

  

Enter Salary: 100 Enter gender: Tax 0.00

Thanks for the help.

    
asked by anonymous 11.12.2014 / 18:03

4 answers

3

getchar() is not a good option for reading 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 the E key and then the Enter key 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 remainder intact:

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

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

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

The problem is that if your program executes the getchar() function again, and the user presses any other key (such as F , for example), the new data would be inserted at the end of the buffer :

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

So the next run of getchar() would return \n instead of F , and you'd get 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 there is nothing on the buffer. That's why the @mutley answer is important. Some people may still recommend running the fflush(stdin) function after getchar() but this is highly inappropriate because fflush() is only used to clear an output stream. Using it in an input stream such as stdin causes undefined behavior.

Alternatively, it is recommended to use fgets() with stdin .

    
12.12.2014 / 13:59
3

You can use the following line, along with the includes of 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 did not read it, the source of my answer suggested you read this link , this link and more this link .

Font

    
11.12.2014 / 18:23
1

The function I use is similar to the one 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, not just when the condition is '\n' .

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

    
22.04.2015 / 02:45
0

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

scanf("%f\n",&salario);
scanf ("%c",&sexo);
    
15.12.2014 / 05:43