Login Esegui login | Non sei registrato? Iscriviti ora (è gratuito!)
Username: Password:
  • Annuncio Pubblicitario

[C++] Gestione eccezione su variabile int

Il forum per tutti i developer. Leggere attentamente il regolamento di sezione prima di postare.

[C++] Gestione eccezione su variabile int

Messaggioda BassMan92 » gio ott 06, 2011 11:34 am

Salve..sono da giorni che lavoro su un problemino. Se io ho una variabile di tipo int e non voglio che l'utente inserisca lettere come faccio?

Per spiegarmi meglio:

Codice: Seleziona tutto
...
int a;

cout << "Scrivi un numero: ";
cin << a;

//CONTROLLO INSERIMENTO (??)

se inserita lettera stampa fail
se invece inserisce un numero stampa il numero


Ma per controllare che l'utente digiti SOLO numeri?
Avatar utente
BassMan92
Aficionado
Aficionado
 
Messaggi: 44
Iscritto il: mer nov 17, 2010 1:46 pm

Re: [C++] Gestione eccezione su variabile int

Messaggioda M@ttia » gio ott 06, 2011 4:34 pm

Codice: Seleziona tutto
#include<iostream>
using namespace std;

int main()
{
   int a;
   cout << "Scrivi un numero: ";
   if (cin >> a)
   {
      cout << "OK!";
   }
   else
   {
      cout << "NO!";
   }   
   
 
   cout << "\n";   
   return 0;
}
</IE><FIREFOX>
Avatar utente
M@ttia
Moderatore
Moderatore
 
Messaggi: 8363
Iscritto il: lun giu 09, 2003 2:18 pm
Località: Ticino - Estero

Re: [C++] Gestione eccezione su variabile int

Messaggioda BassMan92 » gio ott 06, 2011 4:57 pm

Non funziona..mi pareva troppo facile..l'ho fatto anche con il cin.fail() ma il problema è che se inserisco z o z4 mi da errore, ma se dovessi inserire 4z me lo rileva giusto leggendo solo il 4..
Avatar utente
BassMan92
Aficionado
Aficionado
 
Messaggi: 44
Iscritto il: mer nov 17, 2010 1:46 pm


Re: [C++] Gestione eccezione su variabile int

Messaggioda M@ttia » gio ott 06, 2011 6:02 pm

Sì questo è il comportamento standard: legge l'input da sinistra a destra e, finché risulta valido o trova uno spazio, lo salva, ignorando il resto (che è il comportamento spesso preferito)...

Se però proprio vuoi che anche 4z venga riconosciuto come falso, allora fai:

Codice: Seleziona tutto
#include<iostream>
#include <limits>
using namespace std;

int main()
{
   int a;
   cout << "Scrivi un numero: ";
   cin >> a;
   
   cin.ignore(numeric_limits<int>::max(), '\n');

   if (!cin || cin.gcount() != 1)
   {
      cout << "NO!";
   }
   else
   {
      cout << "SI!";
   }   
   

   cout << "\n";   
   return 0;
}
</IE><FIREFOX>
Avatar utente
M@ttia
Moderatore
Moderatore
 
Messaggi: 8363
Iscritto il: lun giu 09, 2003 2:18 pm
Località: Ticino - Estero

Re: [C++] Gestione eccezione su variabile int

Messaggioda BassMan92 » gio ott 06, 2011 6:45 pm

Dovrebbe funzionare..grazie..ma mi spieghi il codice?
Avatar utente
BassMan92
Aficionado
Aficionado
 
Messaggi: 44
Iscritto il: mer nov 17, 2010 1:46 pm

Re: [C++] Gestione eccezione su variabile int

Messaggioda 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>
Avatar utente
M@ttia
Moderatore
Moderatore
 
Messaggi: 8363
Iscritto il: lun giu 09, 2003 2:18 pm
Località: Ticino - Estero

Re: [C++] Gestione eccezione su variabile int

Messaggioda BassMan92 » ven ott 07, 2011 8:35 am

Grazie mille..stra esaustivo.. :)
Avatar utente
BassMan92
Aficionado
Aficionado
 
Messaggi: 44
Iscritto il: mer nov 17, 2010 1:46 pm


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 0 ospiti

Powered by phpBB © 2002, 2005, 2007, 2008 phpBB Group
Traduzione Italiana phpBB.it

megalab.it: testata telematica quotidiana registrata al Tribunale di Cosenza n. 22/09 del 13.08.2009, editore Master New Media S.r.l.; © Copyright 2008 Master New Media S.r.l. a socio unico - P.I. 02947530784. GRUPPO EDIZIONI MASTER Spa Tutti i diritti sono riservati. Per la pubblicità: Master Advertising