Anche se si tratta di un problema abbastanza banale, ho notato che spesso si incespica in errori dovuti alla differente natura delle istruzioni di input del C, scanf e getchar, quando queste sono accodate l’una dopo l’altra per prelevare determinati valori inseriti dall’utente. Il problema è dato dal fatto che dopo una scanf rimane nel buffer della tastiera il carattere di new line (nuova linea), ovvero, più semplicemente, la pressione del tasto “invio” stesso. Tale invio forza in automatico una “digitazione fantasma” nella eventuale successiva istruzione getchar.
Il piccolo programmino di seguito dovrebbe chiarire il problema e presentare la possibile soluzione:
#include <stdio.h> #include <stdlib.h> int main(int argc, char argv[]) { printf("INPUT DA ESAURIMENTO\n"); char ch1, ch2; printf("Inserisci il primo carattere: "); scanf("%c", &ch1); printf("Inserisci il secondo carattere: "); ch2 = getchar(); printf("ch1=%c, Valore ASCII = %d\n", ch1, ch1); printf("ch2=%c, Valore ASCII = %d\n", ch2, ch2); printf("RIPROVA, SARAI PIU' FORTUNATO ;)\n"); printf("Inserisci il primo carattere: "); scanf("%c", &ch1); fflush(stdin); printf("Inserisci il secondo carattere: "); ch2 = getchar(); printf("ch1=%c, Valore ASCII = %d\n", ch1, ch1); printf("ch2=%c, Valore ASCII = %d\n", ch2, ch2); return 0; }
Come si può vedere, il codice prima simula la situazione di errore e poi ci mette una pezza. Ci sono due modi principali per farlo.
Il primo è di usare la funzione
fflush(stdin);
che provvede a svuotare il buffer in questione, subito dopo la scanf e prima della getchar. Il problema che potremmo avere con tale funzione è che essa non è propriamente standard.
L’alternativa è di usare, al suo posto, la riga di codice:
while ( getchar() != '\n' );
che cicla fino a beccare, e mandare ramengo 😉 il newline.
Per rendere ancora più interessante l’esempio stampiamo anche il codice ASCII dei caratteri inseriti. Nella prima parte dell’esecuzione si può allora toccare con mano la problematica appena illustrata osservando che il carattere ch2 ha come codice ASCII il valore 10 che corrisponde proprio al LF (Line Feed – https://it.wikipedia.org/wiki/Ritorno_a_capo) .
Carlo A. Mazzone