View Full Version : Help C++
morpheus72
08-05-2003, 18:34
Ciao a tutti,
Ho un problema con C++...
Come faccio a sapere se una variabile inserita tramite cin>>x; è
un double oppure no?
Grazie
double x;
if(cin >> x)
cout << "Giusto" << endl;
else
cout << "Sbagliato" << endl;
morpheus72
09-05-2003, 08:34
grazie per la risposta, però non ho capito come posso usarlo qui:
int n =0;
while (n<5) { //controlliamo che i lati siano più di 4
cout<<"Inserisci il numero dei lati ( >4 ): ";
cin>>n;
}
Ho provato a mettere quel controllo in diversi modi ma se inserisco un carattere va in loop
:muro:
l.golinelli
09-05-2003, 08:56
int x;
do
{
if(cin >> x)
cout << "Giusto" << endl;
else
cout << "Sbagliato" << endl;
}
while(x < 5);
morpheus72
09-05-2003, 09:04
anche questo codice produce un loop se inserisci un char
do
{
while(!(cin >> x))
cout << "Devi inserire un numero intero" << endl;
if(x >= 5)
cout << "Devi inserire un numero intero minore di 5" << endl;
}
while(x < 5);
morpheus72
09-05-2003, 09:23
ancora loop... :cry:
/\/\@®¢Ø
09-05-2003, 11:11
Bisogna ricordarsi di "ripulire" il canale dopo l'errore... se non lo fai continua a rimanerti il vecchio input, da qui il loop.
ad esempio (non bellissimo lo ammetto :( ):
int n;
while(true)
{
cin >> n;
if ( ! cin )
{
cout << "Non un numero" << endl;
// ripuliamo il canale...
cin.clear();
while( cin.peek() != '\n' )
cin.ignore();
}
else if ( n >= 5 )
cout << "Il numero deve essere < 5 " << endl;
else
{
cout << "Blabla!" << endl;
break;
}
}
/\/\@®¢Ø
09-05-2003, 11:17
In alternativa si puo' usare uno stream sulle stringhe per controllare il tutto:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
/*...*/
int n;
while( true )
{
string s;
cin >> s; // in alternativa getline(cin,s);
istringstream in(s);
in >> n;
if ( ! in )
{
cout << "Non un numero" << endl;
}
else if ( n >= 5 )
{
cout << "Il numero deve essere < 5 !" << endl;
}
else
{
cout << "ok!" << endl;
break;
}
}
Edit : corretto il codice
Ri-ri-edit: maledette tabulazioni ! :D
lombardp
09-05-2003, 11:21
Anche se poco elegante, questo può funzionare? (non provato)
char x[100];
char *stopstring;
long ll;
do {
cin>>x;
ll = strtol(x,stopstring,10);
} while((ll==0) && (!strcmp(x,"0")));
Se poi i numeri devono essere maggiori di 4, si potrebbe fare:
char x[100];
char *stopstring;
long ll;
do {
cin>>x;
ll = strtol(x,stopstring,10);
} while(ll<5);
Mi ero scordato della pulizia ;)
Infatti ho provato e credo che la soluzione più semplice sia questa:
int x;
do
{
while(!(cin >> x))
{
cout << "Devi inserire un numero intero" << endl;
cin.clear(); //elimino i flag di errore
cin.ignore(INT_MAX,'\n'); //ripulisco lo stream
}
if(x < 5)
cout << "Devi inserire un numero intero maggiore di 5" << endl;
}
while(x < 5);
morpheus72
09-05-2003, 12:16
Grazie mille!!!
solo 2 chiarimenti:
1: Cosa fa cin.ignore(); ?
2: cin.ignore(INT_MAX,'\n'); mi da errore INT_MAX (undeclared identifier)
Originally posted by "morpheus72"
Grazie mille!!!
solo 2 chiarimenti:
1: Cosa fa cin.ignore(); ?
2: cin.ignore(INT_MAX,'\n'); mi da errore INT_MAX (undeclared identifier)
cin.ginore() toglie un carattere dallo stream (o non lo toglie se è arrivato alla fine dello stream)...
cin.ignore(INT_MAX,'\n') prende un massimo di INT_MAX caratteri dallo stream fino a quando incrontra \n...
Per includere INT_MAX:
#include <limits.h>
morpheus72
09-05-2003, 15:41
Grande...
Adesso funge tutto!
Ancora thanks :D
morpheus72
09-05-2003, 18:02
Anche se...
se inserisco valori tipo 7,5
legge il 7 come primo input e il valore di input successivo me lo vede come errore (anche se ancora non l'ho digitato)
Quello è normale...
Non so come tu possa evitarlo...
/\/\@®¢Ø
09-05-2003, 18:39
Originally posted by "morpheus72"
Anche se...
se inserisco valori tipo 7,5
legge il 7 come primo input e il valore di input successivo me lo vede come errore (anche se ancora non l'ho digitato)
Se non ricordo male funzioni come strtol si fermano al primo carattere non numerico. E' possibile quindi che lo stream si comporti in modo analogo e si fermi prima della virgola durante la scansione.
Se vuoi evitare questi problemi allora usa il secondo metodo che ti ho suggerito. In questo modo leggerai l'intera stringa "7,5" in s e poi verra' tentata la conversione. In ogni caso dallo stream verranno eliminati tutti e tre i caratteri. Occhio pero' che con questo metodo se scrivi due numeri (separati da spazi) sulla stessa linea sara' come inserire due numeri distinti. Se vuoi invece leggere tutta la riga e ignorare tutti cio' che va oltre al primo valore (che sia testuale o numerico) sostiuisci la riga
cin >> s;
con la riga
getline( cin , s );
per leggere cosi' una riga intera.
Cosi' facendo un input del tipo
3 4.34 fdrr
verra' considerato valido (valore 3)
mentre
a3 1
no.
Edit: dimenticavo: per utilizzare istringstream ricordati di includere l'header <sstream>
(ora correggo anche il codice)
morpheus72
09-05-2003, 19:03
Mi da questo errore di compilazione:
error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> >' (or there is no acceptable conversion)
con getline:
error C2780: 'class std::basic_istream<_E,_Tr> &__cdecl std::getline(class std::basic_istream<_E,_Tr> &,class std::basic_string<_E,_Tr,_A> &,const _
E)' : expects 3 arguments - 2 provided
/\/\@®¢Ø
09-05-2003, 19:20
Usi il compilatore della Microsoft ?
Originally posted by "morpheus72"
Mi da questo errore di compilazione:
error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> >' (or there is no acceptable conversion)
:confused:
Questo non lo capisco proprio... non esiste l'operatore '>>' per le string !?!?!?!?
error C2780: 'class std::basic_istream<_E,_Tr> &__cdecl std::getline(class std::basic_istream<_E,_Tr> &,class std::basic_string<_E,_Tr,_A> &,const _
E)' : expects 3 arguments - 2 provided
Sembra che non utilizzi il parametro di default :confused:
Con
getline(cin , s , '\n' )
questo dovrebbe andare.
Sinceramente il primo errore e' proprio strano ! L'unica cosa che posso dire e'.... controlla se non ci sono errori di battitura su cin :D, altrimenti non puoi che incolpare il compilatore, il codice compila correttamente sul mio pc ( compilatore GNU e Intel).
morpheus72
09-05-2003, 20:05
mi puoi dire dove posso scaricare il compilatore che usi?
/\/\@®¢Ø
09-05-2003, 23:56
La cosa piu' semplice forse e' se scarichi Dev-cpp
(http://www.bloodshed.net/devcpp.html, i downloads dovrebbero essere qui: http://sourceforge.net/project/showfiles.php?group_id=10639 ), che contiene il compilatore della gnu e un IDE grafico.
Se non ho letto male il topic:
ti da un errore con 7,5 perchè il separatore decimale di default è il punto.
Il programma setta il "locale" allo startup.
se vuoi che gli streams leggano la virgola invece del punto:
...
#include <locale>
...
using namespace std;
//setta il linguaggio locale del tuo sistema :
//quello che scegli all'installazione
locale::global(locale("")) ;
//reimposta il locale per lo stream di output
//che allo startup viene settato come asci standard (che ha il punto)
cout.imbue(locale(""));
...
cout<<"Scrive con la virgola 7,5+2,5 "<<(7,5+2,5)<<'\n';
...
morpheus72
10-05-2003, 08:04
Non è che voglio usare la virgola al posto del punto...
vorrei che se per errore l'utente dovesse digitare 7,6 invece di 7.6 il programma segnalasse l'errore
Come includi iostream ?
Così ?
#include <iostream.h>
o così ?
àinclude <iostream>
morpheus72
10-05-2003, 12:24
Originally posted by "cionci"
Come includi iostream ?
Così ?
#include <iostream.h>
o così ?
àinclude <iostream>
#include <iostream.h>
/\/\@®¢Ø
10-05-2003, 12:38
Originally posted by "morpheus72"
#include <iostream.h>
Gli header del C++ (non del C!) vanno scritti sempre senza il .h ( <string> <map> <iostream> etc. )
Anche se esiste la versione corrispondente col .h ( <string.h> ad esempio) si tratta di header "vecchi" tenuti per compatibilita' col vecchio codice. Prova a togliere il .h da iostream e dimmi se ti da ancora errore, include anche l'header <string>.
Se usi la versione con
cin >> s;
(e non quella col getline)
allora prova a modificare la linea
if ( ! in )
con
if ( ! in || in.peek() != EOF )
In questo modo se hai un input come 4f non verra' letto come 4 ma come stringa sbagliata. (mentre prima si limitava ad ignorare la parte rimanente).
Ovviamente devi aggiungere dopo gli include:
using namespace std;
morpheus72
10-05-2003, 12:57
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void main(int, char* []) {
double n;
while( true )
{
string s;
cin >> s;
istringstream in(s);
in >> n;
if ( ! in || in.peek() != EOF ) {
cout << "Non un numero" << endl;
}
else if ( n >= 5 ) {
cout << "Il numero deve essere < 5 !" << endl;
}
else {
cout << "ok!" << endl;
break;
}
}
}
Così finalmente funziona tutto alla perfezione!
Grazie a tutti
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.