PDA

Visualizza la versione completa : [C++] assegnare una carattere a un intero


m4st3r
20-12-2008, 19:16
ciao a tutti volevo esporvi un problema che ho riscontrato nel mio programma...ad es nella funzione menu:



int menu(int &abbonato)
{int scelta;
char risp;
do
{
clrscr();
cout << " ***PROGRAMMA GESTIONE PARCHEGGIO***"<<endl<<endl<<endl;
cout << "Scegliere una delle seguenti opzioni: (1,2,3,4,5)"<<endl<<endl;
cout << "1 -->
cout << "2 -->
cout << "4 -->
cout << "5 -->
cin >> scelta;


}
while (scelta<1 || scelta>5);
return scelta;
}


il menu chiede all'utente di effettuare una scelta, e si aspetta di ricevere un intero (1,2,3,4,5)

per evitare errori ho messo il ciclo while che controlli che la scelta sia compresa tra 1 e 5, il problema c'è se l'utente inserisce una lettera...il programma si blocca completamente...come posso fare per ovviare a questo problema?

MacApp
20-12-2008, 20:10
il tuo programma non e' compilabile.

sotoli
21-12-2008, 15:30
Ciao.....a parte la mancanza di molti ';', per risolvere il tuo problema basta sostituire:

cin >> scelta;
con

scelta = cin.get();

e cambiare il while da così:


while (scelta<1 || scelta>5);
a così:

while (scelta<'1' || scelta>'5');

MItaly
21-12-2008, 15:46
In alternativa, se vuoi continuare ad acquisire un intero e non un carattere, dai un'occhiata qui (http://forum.html.it/forum/showthread.php?threadid=1284194).

m4st3r
21-12-2008, 19:48
Originariamente inviato da sotoli
Ciao.....a parte la mancanza di molti ';', per risolvere il tuo problema basta sostituire:

cin >> scelta;
con

scelta = cin.get();

e cambiare il while da così:


while (scelta<1 || scelta>5);
a così:

while (scelta<'1' || scelta>'5');

quello che mi dici di fare è di far diventare la variabile scelta un char?

per quando riguarda il cin.fail() non ho capito bene a cosa servono il cin.clear e sync che mettono dopo...grazie mille

MItaly
21-12-2008, 20:26
Servono per resettare il failbit e svuotare il buffer di lettura; quando dici a cin di acquisire un intero, se vede che non può considerare i caratteri inseriti un intero, li lascia nel buffer di input e imposta il failbit; se controllando il failbit (cin.fail()) vedi che è impostato, significa che l'utente non ha inserito un numero. In questo caso svuoti il buffer di input (cin.sync()), eliminando così i caratteri errati appena inseriti, e disattivi il failbit (cin.clear()).

sotoli
21-12-2008, 20:29
Originariamente inviato da m4st3r
quello che mi dici di fare è di far diventare la variabile scelta un char?


No....cin.get() ritorna un int che rappresenta la codifica ascii del carattere digitato (leggi qui (http://www.cplusplus.com/reference/iostream/istream/get.html))

Se ti è più chiaro, invece di scrivere:

while (scelta<'1' || scelta>'5');
puoi anche scrivere

while (scelta<49 || scelta>53);

poiché 49 è la codifica ascii di 1 e 53 è quella di 5.

L'unica cosa che cambia e di cui mi sono accorto ora è che il valore di ritorno della tua funzione cambia, non è più compreso tra 1 e 5 ma tra 49 e 53.
Per correggere questo errore puoi scrivere

return (scelta - 48);
al posto di

return scelta;

m4st3r
21-12-2008, 21:13
mmm ho capito grazie mille...se invece adottassi questa soluzione:



int menu(int &abbonato)
{int scelta;
char buffer[50];
char risp;
do
{clrscr();

cout << ;
cout << "1 -;
cout << "2 -;
cout << ;
cout << ";
cout << ;

cin.getline(buffer,20);
scelta=atoi(buffer);

if (scelta == 1 )
{ clrscr();
cout << "Benvenuto! E' un cliente abbonato? s/n"<<endl;
cout << endl <<"[Se sei un nuovo cliente e vuoi sottoscrivere un abbonamento"<<endl;
cout << "torna al menu principale premendo Q]"<<endl;
cin >> risp;
if (risp=='s' || risp == 'S')
abbonato = 0;
if (risp =='q' || risp == 'Q')
return 0;
}

if (scelta<1 || scelta>5)
{
cout << endl << "La scelta che hai fatto e' errata ti prego di riprovare"<<endl<<endl;
system("pause");

}
}
while (scelta<1 || scelta>5);
return scelta;
}



//PROGRAMMA PRINCIPALE




int main()
{ int scelta;
int abbonato;
int conta = 1;
int codice=1;

do
{abbonato = -1;
scelta = menu(abbonato);

switch(scelta)
{
case 1:
;
}
else ;
break;
case 2:
findTagliando();
break;
case 3:

break;
case 4:
clean();
break;
case 5:
write();
return 0;
default:
break;
}
}
while (scelta != 5);
system("pause");
return 0;
}



allora a parte il resto del programma quello che mi interessa è questo



cin.getline(buffer,20);
scelta=atoi(buffer);


in pratica prima leggo come carattere e salvo nel buffer e poi attraverso atoi converto la stringa in intero.

La cosa sembra funzionare...non capisco pero' come mai dopo la prima volta (in cui funziona) alla seconda ripetizione (infatti è inserita in un ciclo come potete vedere nel main) non mi chiede piu di inserire il numero ma salta direttamente all' if



if (scelta<1 || scelta>5)
{
cout << endl << "La scelta che hai fatto e' errata ti prego di riprovare"<<endl<<endl;
system("pause");

}


ho provato a capire come mai e ho scoperto che alla seconda ripetizione senza chidermi niente la scelta diventa = 0...come mai?

m4st3r
21-12-2008, 22:53
se faccio



cin >> buffer;
scelta=atoi(buffer);


al posto di



cin.getline(buffer,20);
scelta=atoi(buffer);


funziona!!! :) :unz:

ora mi rimarrebbe la curiosita di capire cosa cambia :master:

MItaly
22-12-2008, 15:54
Se mischi funzioni di input formattate e non formattate puoi avere problemi derivanti dai caratteri lasciati nel buffer dello stream; puoi ovviare al problema mettendo prima di ogni input un


cin.sync();
.

Loading