Cleaning the Buffer after getchar

Asked

Viewed 1,489 times

3

Good Morning,

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

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

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

Introducing the following Output without letting me enter sex:

Enter Salary: 100 Enter Gender: Tax 0.00

Thanks for the help.

4 answers

3


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 the button 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() be executed:

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

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

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

Thus, the next execution of getchar() would return the \n instead of F, and you would get the impression that your program doesn’t work.

In this way, it is extremely necessary to clean the input buffer after running getchar() so there’s nothing left in the buffer. That’s why the @Mutley is important. Some people may even recommend running the function fflush(stdin) after getchar() but this is highly inappropriate because fflush() serves only to clear an output stream. Use it in an input stream like stdin, causes undefined behavior (Undefined behavior).

As an alternative, the use of fgets() with stdin.

  • Out of curiosity What would happen if we used getchar() if the buffer was empty.

  • The code would stop, waiting for a keyboard input.

  • Our Is Really, I Knew It And Flying, I Use Direct getchar() To Pause asuashsuahusa

3

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 though you didn’t read it, the source of my reply suggested you read it that link, this link and more this link.

Source

1

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

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

  • has to be int c for use with EOF

  • End of File. End of file is type independent.

  • https://repl.it/@Mateusschroeder/Type-EOF (therefore not independent of type), and in the draft: §7.21.1 "which expands to an integer Constant Expression, with type int and a Negative value, that is returned by several functions to indicate end-of-file, that is, no more input from a stream;" and that other issue here https://softwareengineering.stackexchange.com/a/197629

0

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

scanf("%f\n",&salario);
scanf ("%c",&sexo);
  • In fact, this will only skip one line after reading the entry.

  • which is exactly what he needs: read the salary on one line and sex on the other.

  • What I mean is, it won’t change the input at all.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.