da M@ttia » ven ott 07, 2011 1:42 am
Allora, come premessa generale, come ti ho spiegato sopra, quando noi scriviamo
- Codice: Seleziona tutto
cin >> a;
C++ sa già che a è di tipo int, pertanto legge l'input che gli diamo SOLO FINTANTO CHE SI TRATTA DI NUMERI (CIFRE 0-9); appena incontra una lettera sa che essa non può essere assegnata all'int a, quindi si ferma (questo è il motivo per cui digitando 4z ti ritrovi con a=4).
La cosa importante è però che tutto ciò che non è stato letto rimane nel cin. Da notare che ogni input finisce sempre (anche se non visualizzato) con un simbolo "\n", ovvero il simbolo che in C++ indica l'inizio di una nuova riga (sempre implicitamente presente alla fine di una riga di input).
- Consideriamo allora la prima "inncoua" parte di codice
- Codice: Seleziona tutto
cin >> a;
Nonostante sembri una riga facile, alla luce di quanto spiegato sopra quello che in verità accade "sotto il cofano" è un po' più articolato di "salvo l'input in a". Limitandoci a ciò che interessa a noi, elenco qua sotto 4 esempi recanti 4 possibili tipologie di input.
Esempio 1:
Input Utente = '48'
Il risultato sarà a=48 e cin='\n'
Esempio 2:
Input Utente = '48pqr'
Il risultato sarà a=48 e cin='pqr\n'
Esempio 3:
Input Utente = '48pqrs50'
Il risultato sarà a=48 e cin='pqrs50\n'
Esempio 4:
Input Utente = 'pqr'
Il risultato sarà a=indefinito (sarà un valore numerico enorme casuale, o il numero più grande esprimibile con int a seconda del compilatore usato e della memoria RAM in quel preciso momento; in ogni caso è un valore inaffidabile e da considerarsi INDEFINITO) e cin=indefinito (non è esattamente vero, ma per non addentrarci in tecnicismi inutili interpretiamolo come indefinito; in particolare NON CONTIENE NEMMENO IL SIMOBOLO \n)
- Prossimo pezzo:
- Codice: Seleziona tutto
cin.ignore(numeric_limits<int>::max(), '\n');
La Funzione cin.ignore(NUMERO,SIMBOLO) elimina da cin tutti i CARATTERI, finché non ne ha eliminati NUMERO tanti oppure ha raggiunto il simbolo SIMBOLO (eliminando anch'esso!).
numeric_limits<int>::max() è un modo da sboroni per rappresentare il numero più grande esprimibile con un int sulla macchina attuale (nel nostro caso può benissimo essere rimpiazzato da un 1000 o simile volendo...)
Il risultato di questo pezzo di codice è allora quello di eliminare tutti i caratteri da cin rimasti. Sempre seguendo la numerazione dei 4 esempi sopra avremo dopo questa operazione:
Esempio 1: cin = vuoto (ha eliminato 1 simbolo \n)
Esempio 2: cin = vuoto (ha eliminato i 3 caratteri pqr + 1 simbolo \n)
Esempio 3: cin = 50 (ha eliminato i 4 caratteri pqrs + 1 simbolo \n)
Esempio 4: cin = indefinito (ha eliminato 0 caratteri e 0 simboli \n)
- Ultimo pezzo:
- Codice: Seleziona tutto
if (!cin || cin.gcount() != 1)
Come vedi dai 4 risultati subito qui sopra, non basta verificare che cin=vuoto (dato che Esempio 1 e 2 hanno entrambi questa proprietà, ma l'1 è Ok mentre il 2 no...).
Ci viene pertanto in soccorso la funzione cin.gcount(), che ci ritorna il NUMERO DI CARATTERI/SIMBOLI ELIMINATI DURANTE L'ULTIMA CHIAMATA DI cin.ignore(...) (a dire il vero vale anche per la chiamata ad altre funzioni quali cin.get, cin.getline, cin.peek, ecc., ma noi abbiamo usato solo cin.ignore()).
Se abbiamo inserito un solo valore numerico (vedi Esempio 1), cin.ignore() ha eliminato esattamente 1 cosa (il simbolo \n); quaslaisi altro numero di cose eliminate indica che l'input non era valido. Con cin.gcount() != 1 verifichiamo quindi se è stato eliminato un numero di cose diverso da 1 (che è l'unico giusto per un input valido).
</IE><FIREFOX>