Molti docenti evitano di discutere taluni aspetti "nascosti" delle funzioni, esposti peraltro molto chiaramente in
letteratura, probabilmente per timore di confondere le idee e/o per non perdere la comodità e l'immediatezza didattica di ricorrere a certe funzioni-segnaposto, ancorché ampiamente sconsigliate nel codice professionale.
Purtroppo anche gets() è fattualmente deprecata nei manuali di stile (vedi la seconda parte della bibliografia linkata): molto meglio ricorrere alla fgets() su stdin per l'unput di stringhe, con una serie di vantaggi in robustezza, efficienza e controllo del numero massimo di caratteri immessi nel buffer.
Naturalmente è sempre possibile (e talora necessario) continuare ad abbinare l'idioma segnalato per la pulizia del keyboard buffer, come suggerisce il seguente esempio.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {FALSE, TRUE} boole_t;
#define MAX_LEN 20
void ClearKeyboardBuffer(void)
{
char ch;
while ((ch = getchar() != '\n') && (ch != EOF));
}
boole_t get_string(char **buff, size_t max_chars_to_read, boole_t purge, boole_t trim_CRLF)
{
char *p;
*buff = (char *)malloc(max_chars_to_read +1);
if (NULL == *buff)
{
return FALSE;
}
if (NULL == fgets(*buff, max_chars_to_read +1, stdin))
{
free(*buff);
return FALSE;
}
p = strrchr(*buff, '\n');
if (NULL != p)
{
if (trim_CRLF)
{
*p = '\0';
}
}
else
{
if (purge)
{
ClearKeyboardBuffer();
}
}
return TRUE;
}
int main()
{
char *b;
boole_t res;
printf("Immetti una stringa (max %d caratteri): ", MAX_LEN);
res = get_string(&b, MAX_LEN, FALSE, TRUE);
if (res)
{
printf("Stringa immessa: (%d) \"%s\"", strlen(b), b);
free(b);
}
ClearKeyboardBuffer();
printf("\nImmetti una stringa (max %d caratteri): ", MAX_LEN);
res = get_string(&b, MAX_LEN, TRUE, FALSE);
if (res)
{
printf("Stringa immessa: (%d) \"%s\"", strlen(b), b);
free(b);
}
return EXIT_SUCCESS;
}
L'esempio è tratto da
questo thread, dove era stato presentato in forma volutamente incompleta per stimolare una riflessione dell'OP su alcune necessarie modifiche. Mi scuso in anticipo per eventuali errori commessi nel risistemarlo "al volo" su uno smartphone.