• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Problema Scanf intero di caratteri produce buffer

AnonyTrack

Utente Attivo
Autore del topic
16 Gennaio 2012
410
56
Miglior risposta
0
Salve, sto creando un programma che verifica se il tasto digitato sia un numero.
Allo scanf("%d", &x); io voglio che l'utente digiti un numero intero da 1 a 100.
Ora, mi sono chiesto cosa sarebbe accaduto se l'utente invece di digitare il numero 56, avrebbe digitato caratteri a caso per creare caos nel codice, ad esempio 'ciao' o 'ciao22' o '22ciao'..
Dato che lo scanf preleva l'intero, ho notato che nel mio programma, se inserisco un numero tra 1 e 100 continua normalmente, se inserisco delle lettere e numeri, mi crea una specie di buffer ovvero memorizza i caratteri e ogni volta allo scanf li rialloca e li ripete (o almeno io penso).
L'output che esce a schermo è un loop continuo senza fine del printf '# chiave numerica 'x':' e il printf dell'errore 'valore numerico errato'. Se invece digito nello scanf 'ciao200' mi da sempre il loop però col messaggio di errore 'massimo 100' ovvero quello di dove verifica se il numero è massimo 100.
Questo è il codice così capite meglio:

Punto del codice dove chiede il numero:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Funzione esterna 'isnumero' dove lo analizza:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

I valori di ritorno:
return 0 interrompe il ciclo while e continua
return 1 esce dalla funzione isnumero e va allo scanf (quindi ripete il while)
return 2 errore, esce dal programma

Cosa posso fare?
Grazie a chi sa aiutarmi
 
Partiamo dal presupposto che scanf() può essere facilmente utilizzata male. Come tutta la libreria standard del C è stata fatta per tempi in cui le performance erano di primaria importanza, più della sicurezza o dell'astrazione.

Detto questo, tentare di prendere in input un numero e inserire un carattere è chiaramente una violazione delle tue condizioni. Non essendoci controlli da parte della funzione è necessario che sia tu a gestire tutte le possibili condizioni d'errore.

Innanzitutto quella che ti viene data in input è una sequenza di caratteri, quindi trattala come tale. Imponi magari un limite sulla lunghezza che ti aspetti:
C:
Perfavore, Entra oppure Registrati per vedere i codici!
Tramite opportuni controlli sul numero di caratteri letti da scanf() o comunque conoscendo a priori la dimensione massima che accetti per il numero puoi chiamare in sicurezza
Perfavore, Entra oppure Registrati per vedere i Link!
:
C:
Perfavore, Entra oppure Registrati per vedere i codici!
In alternativa considera di utilizzare anche
Perfavore, Entra oppure Registrati per vedere i Link!
che è più robusta.

Quindi, che tu abbia convertito manualmente o tramite funzioni preesistenti, adesso ti ritrovi comunque con un numero (valido o meno).

Se invece vuoi controllare che ogni carattere sia numerico puoi ciclare con isdigit() e controllare che sia diverso da zero. Tra l'altro nel tuo codice c'è anche questo errore in quanto fai l'uguaglianza con zero.

Sempre parlando del tuo codice ti conviene riscrivere le condizioni if-else, così tanti return possono magari essere resi più leggibili tramite uno switch-case. Inoltre serve un return esterno a tutto sempre nella funzione isnumero().