我为什么要在这个程序中使用fflush(stdin)?

时间:2015-07-12 22:47:31

标签: c struct

我知道清洁键盘缓冲区是有用的,但是我不明白何时/为什么需要使用它或者我真的需要。

例如,在我为我的课程编写的代码中,只有在我fflush(stdin)之后立即将while放入主函数时,它才有用,我只知道这一点,因为教授告诉我在我向他展示了错误之后这样做了。

问题是否与 struct 有关,这就是为什么我应该使用 fflush(stdin)

以下是代码:

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

2 个答案:

答案 0 :(得分:4)

实际上,如果谈到标准 C,教授是错的。根据标准,在输入流(例如fflush)上调用stdin是未定义的行为。< / p>

但是,在许多实现中(包括Linux†,OS X,各种BSD等)fflush(stdin)会丢弃已缓冲但尚未使用的任何输入。程序中使用此非标准功能清除前一个scanf在输入缓冲区中留下的尾部换行符。

Linux上的

man fflush非常友好地提到这是非标准的(尽管措辞并未表明未定义的行为):

  

标准没有指定输入流的行为。

同时 7.21.5.2下的C11标准fflush函数表示:

  

如果stream指向输入流或未输入最新操作的更新流,则fflush函数会将该流的任何未写入数据传递到主机环境被写入文件;否则,行为未定义。

†根据评论,这种非标准行为可能不适用于Linux,尽管man fflush声称应该这样做。

答案 1 :(得分:0)

  1. 您不应在C程序中使用fflush(stdin)。它没有明确定义。它不便携。

  2. 您不应该需要在C程序中使用fflush(stdin)。可悲的是,唯一一次出现这种需求的时候是程序员正在学习C并且使用scanf很多并且在scanf的一个明显的困难中得到了bin。简单地说,停止使用scanf并且“需要”来清除输入消失。或者,插入对getchar的额外调用,或者读取并丢弃输入到新行的循环,如其他地方所述。