问题
I know that it is use to clean the keyboard buffer, but I don't understand when/why I need to use it or if I really need to.
For example, into this code that I made for my class, it only works if I put fflush(stdin) into the main function right after the while, and I only know this because the professor told me to do so after I had showed him the erro.
Does the problem have something related with the struct and thats why I should use fflush(stdin)?
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct CLIENTES
{
int ano_nasc, cpf[11];
float renda_m;
char nome[50];
}; //Lista de Objetos
int main(void)
{
//Declaracao de Variaveis
int cont=0, num, num_2, client, i, j;
CLIENTES *vet;
//Leitura de Dados
printf("Digite o numero de Clientes: ");
scanf("%d%*c", &num);
vet = (CLIENTES*)malloc(num*sizeof(*vet));
printf("Digite os Dados do Cliente.");
while (cont != num)
{
fflush(stdin);
printf("\nNome: ");
fgets(vet[cont].nome, sizeof(vet[cont].nome), stdin);
printf("\nAno de Nascimento: ");
scanf("%d", &vet[cont].ano_nasc);
printf("\nCPF: ");
scanf("%d", &vet[cont].cpf);
printf("\nRenda Mensal: ");
scanf("%f", &vet[cont].renda_m);
cont++;
}
printf("\nDigite o numero do cliente que voce deseja conferir: ");
scanf("%d", &num_2);
for (i=0;i<num;i++)
{
if(num_2 == num)
{
printf("\nO que deseja saber sobre ele?\n");
printf("1-Nome\n2-Ano de Nascimento\n3-CPF\n4-Renda Mensal\n\n\n");
scanf("%d", &client);
if (client == 1)
{
printf("Nome: %s", vet[(num_2)-1].nome );
}
else if(client == 2)
{
printf("Ano de Nascimento: %d", vet[num_2].ano_nasc );
}
else if(client == 3)
{
for(j=0;j<11;j++)
{
printf("CPF: %d", vet[num_2].cpf[j]);
}
}
else if(client == 4)
{
printf("Renda Mensal: %f", vet[num_2].renda_m );
}
}
}
//Finalizando o Programa
printf("\n\nFim do Programa!");
getch();
return 0;
}
回答1:
Actually the professor is wrong if speaking of standard C. According to the standard, calling fflush on an input stream (such as stdin) is undefined behaviour.
However, in many implementations (including Linux†, OS X, various BSDs, etc.) fflush(stdin) discards any input that has been buffered but not yet consumed. This non-standard feature is used in your program to clear the trailing newline left in the input buffer by the previous scanf.
man fflush on Linux is kind enough to mention that this is non-standard (although the wording doesn't quite suggest undefined behaviour):
The standards do not specify the behavior for input streams.
Meanwhile the C11 standard under 7.21.5.2 The fflush function says:
If
streampoints to an output stream or an update stream in which the most recent operation was not input, thefflushfunction causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
† According to comments this non-standard behaviour may not work on Linux despite man fflush claiming that it should.
回答2:
You should not use
fflush(stdin)in a C program. It's not well-defined. It's not portable.You should not need to use
fflush(stdin)in a C program. The only time this need comes up, sadly, is when progammers are learning C and usingscanfa lot and getting bin by one ofscanf's notoriousl difficulties. Simply put, stop usingscanfand the "need" to flush input goes away. Or, insert extra calls togetchar, or loops that read and discard input up to a newline, as described elsewhere.
来源:https://stackoverflow.com/questions/31373337/why-should-i-use-fflushstdin-in-this-program