Sé que se usa para limpiar el búfer del teclado, pero no entiendo cuándo/por qué necesito usarlo o si realmente lo necesito.
Por ejemplo, en este código que hice para mi clase, solo funciona si pongo fflush(stdin) en la función principal justo después del while , y solo sé esto porque el profesor me dijo que lo hiciera después de que le mostré el error
¿El problema tiene algo relacionado con la estructura y por eso debo usar fflush(stdin) ?
Aquí está el código:
#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; }En realidad, el profesor está equivocado si habla del estándar C. De acuerdo con el estándar, llamar a fflush en un flujo de entrada (como stdin ) es un comportamiento indefinido.
Sin embargo, en muchas implementaciones (incluyendo Linux†, OS X, varios BSD, etc.) fflush(stdin) descarta cualquier entrada que se haya almacenado en el búfer pero que aún no se haya consumido. Esta característica no estándar se usa en su programa para borrar la nueva línea final que quedó en el búfer de entrada por el scanf anterior.
man fflush en Linux tiene la amabilidad de mencionar que esto no es estándar (aunque la redacción no sugiere un comportamiento indefinido):
Los estándares no especifican el comportamiento de los flujos de entrada.
Mientras tanto, el estándar C11 bajo 7.21.5.2 La función fflush dice:
Si el
streamapunta a un flujo de salida o un flujo de actualización en el que no se ingresó la operación más reciente, la funciónfflushhace que cualquier dato no escrito para ese flujo que se entregue al entorno host se escriba en el archivo; de lo contrario, el comportamiento no está definido.
† Según los comentarios, es posible que este comportamiento no estándar no funcione en Linux a pesar man fflush afirma que debería hacerlo.
No debe usar fflush(stdin) en un programa C. No está bien definido. No es portátil.
No debería necesitar usar fflush(stdin) en un programa C. La única vez que surge esta necesidad, lamentablemente, es cuando los programadores están aprendiendo C y usando mucho scanf y obteniendo bin por una de las notorias dificultades de scanf . En pocas palabras, deje de usar scanf y la "necesidad" de vaciar la entrada desaparecerá. O bien, inserte llamadas adicionales a getchar , o bucles que lean y descarten la entrada hasta una nueva línea, como se describe en otra parte.