Newsgroup: it.comp.lang.c
Titolo: [NEWBIE] gestione input errati a scanf()

Ho notato che se si digita una lettera/simbolo in una scanf(%d,&var), il 
programma va avanti e la variabile non viene modificata
(e` normale questo comportamento??)
premetto che sono con LINUX/GCC, perche` piu` di uno mi ha detto che 
sotto win la scanf() in questo caso continuerebbe a richiedere l'input 
finche` non si digita un numero.. (non so se sia vero!!)
bhe comunque cercando un modo per fare controlli sull'input ho scoperto 
che il return value di scanf() e` zero quando non ha preso `valori' 
validi
chiedendo un `%d' e dando una lettera, il ret.val ho visto che viene 
infatti zero e fin qua tutto ok!
Si puo` mettere la scanf() in un if che magari caccia un errore in caso 
di ritorno=zero.
poi ho messo la scanf() in un do-while in modo da richiedere subito 
l'input in caso di errore... ma non funge come mi aspettavo:
#include <stdio.h>
int main(){
        int n=0,x=0;
        do{} while( (scanf("%d",&n))==0  );
        printf("\nil valore inserito e` %d",n);
        return 0;
}
se inserisco SUBITO un numero, e` OK (esce dal ciclo e printa)
se do` una lettera/simbolo mi richiede l'inserimento, MA POI anche
dando valori numerici, non esce mai piu` dal while (continua a 
richiedere all'infinito il valore)
quindi qualcuno sa spiegare come mai quel codice si comporta in tale 
modo?
altri metodi + intelligenti per controllare gli errori di input da 
tastiera?
grazie anticipatamente,
-- 
    Pardo
 
http://pardo.cjb.net
 
    ( BACKUP: 
http://pardo.tsx.org
 )

 richiedere all'infinito il valore)
Buffer dirty.
int r, n;
do {
        r = scanf("%d", &n);
        while(getchar() != '\n')
                ;
} while(r == 0);
printf("\nil valore inserito e` %d\n", n);
ciao
Kronos
PS: ti sei dato al C? ;) Ci si vede allo SMAU!
-- 
Home: 
http://kronoz.cjb.net
"Ci sono le balle , le megaballe e le statistiche".
 Mark Twain

 
Cosi` funge ma e` cio` che succede `internamente' che non mi e` 
abbastanza chiaro..
Cioe` la scanf continua a prendere la roba inserita prima?? O che?! 
boooh
L'unico modo x levarmi i dubbi e` guardare direttamente il source della 
libbreria..... [sapendo ke non ci capiro` niente]
grazie ciaoooo,


 boooh
Le funzioni di lettura standard del C non leggono i tasti premuti, ma 
leggono da un buffer.
Se nel buffer ci metti 20 caratteri e al passo successivo ne leggi solo 10, 
te ne resteranno 10.
Alla successivo inserimento di 15 caratteri, verranno memorizzati in coda a 
restanti 10 (arriviamo a un totale di 25).
A una successiva lettura leggi 15 caratteri: ti troverai 10 caratteri del 
primo inserimento, 5 del nuovo (contando anche le newline), creando in 
alcuni casi confusione (se non altro nel povero programmatore che ara 
all'oscuro del meccanismo).
Per evitare problemi hai 2 modi (standard):
- leggere tutti i caratteri presenti, fino alla newline, e poi interpretare 
solo quelli che ti servono (quello che in genere si tenta di fare con una 
fgets() su stdin)
- leggere solo quelli che ti servono e poi avviare un ciclo di lettura fino 
alla successiva newline, senza salvare il risultato.
Nota: l'ultimo carattere inserito sara' sempre una newline.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 boooh
La scanf prende robba fino al newline, ma *non* toglie il newline
dal buffer.Se non lo togli tu il prossimo scanf prendera' tutto 
quello che c'e' nel buffer fino al newline che e' ancora nel 
buffer...cioe' niente.
P.S. non sono proprio sicuro...aspettiamo Kronos per la certezza ;-)
-- 
Il segreto di una vita sana e' lo sport.
Mai farne.

 buffer...cioe' niente.
Peggio :)  Nel caso in  question scanf interrompe la  conversione quando
incontra il primo carattere  non numerico. Inserendo una lettera, questa
rimane nel buffer. E`  per questo che ho usato un  ciclo per svuotare il
buffer: una  singola chiamata  a getchar()  non avrebbe  avuto l'effetto
voluto.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Chi parla in tono cortese, ma continua a prepararsi, potra` andare avanti;
 chi parla in tono bellicoso e avanza rapidamente dovra` ritirarsi" 
Sun Tzu -- L'arte della guerra

        r = scanf("%d", &n);
//>         while(getchar() != '\n')
//>                 ;
          while((q=getchar() )!= '\n' && q!=EOF);
non č meglio? 
