Newsgroup: it.comp.lang.c++
Titolo: Problema di inserimento dei dati

Ciao a tutto l'NG!
Ho un piccolo problema, diciamo, di INPUT/OUTPUT. Se scrivo queste
semplici righe:
#include <iostream>
void main()
{
  int n;
...........
  cout << "Inserisci un intero: ";
  cin >> n;
  cout "\nHai inserito : "<< n << endl;
  cout "cin.fail = "<< cin.fail();
..........
}
ed inserisco al posto dell' intero un carattere non numerico, per
esempio 'a', ottengo il seguente output:
Inserisci un intero: a
Hia inserito: 575
cin.fail = 2
Quando invece inserisco un intero, cin.fail() ritorna 0. Allora ho
pensato di mettere tutto dentro un ciclo del tipo:
do {
  cout << "Inserisci un intero :";
  cin >> n;
  cout << "\nHai inserito : " << n << endl;
} while (cin.fail());
Ma questo ciclo non termina più se inserisco un carattere non numerico!!
Mi trovo questo output:
Inserisci un intero : a
Hai inserito : 575
Inserisci un intero:
Hai inserito: 575
Inserisci un intero:
Hai inserito : 575
.
.
.
.
E così via all' infinito! Cambiando compilatore si ottiene sempre lo
stesso risultato con la sola differenza che il 575 viene sostituito da
altri valori.
Come posso evitare questo problema facendo in modo che il programma
continui solo se l' utente ha inserito un intero?
Mi scuso per la lunghezza del post... non so quanti hanno resistito
fino alla fine!!
Dyskolos
Sent via Deja.com
http://www.deja.com/

 continui solo se l' utente ha inserito un intero?
Ma non e' quello cha hai gia' ottenuto?
O stai cercando di dirci che non esce neppure inserendo un intero?
A meno che quello che ti confonde e' il fatto che premi invio. Beh, in questo
caso sappi che un invio non e' un'intero!
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556


Il problema č che se inserisco un carattere non numerico(e dopo INVIO)
il ciclo non termina piů!!! E, naturalmente, devo interrompere il
programma brutalmente. Se inserisco un intero, il programma prosegue
senza problemi. Provaci e vedrai!!


 Ma questo ciclo non termina più se inserisco un carattere non numerico!!
Intendi dire che non esce dal ciclo anche se nelle iterazioni successive
inserisci un intero o che continua a ciclare senza fermarsi ad aspettare
nuovi input?
Comunque ti conviene verificare se non devi resettare "fail"
esplicitamente. Se questo non basta potrebbero esserci problemi di
svuotamento di buffer o di sincronizzazione tra input e output. Mi
sembra di ricordare che esiste una funzione "tie" per gestire questo
problema.
Ciao,
Nicola

 senza problemi. Provaci e vedrai!!
No. Ho capito cosa intendi anche senza provare. Il problema e' che non hai
"consumato" l'input. Ovvero lui esce con un errore dovuto al fatto che non trova
un intero. Ma non ha ancora letto il carattere non numerico. Ovviamente prima di
ritentare l'input devi leggerti i caratteri che ci sono nel buffer. Per esempio
con
cin.ignore(numeric_limits<int>::max(),'\n');


 nuovi input?
La seconda :-) continua senza aspettare nuovi input.



Grazie Andrea!
  Ma purtroppo non ho risolto il problema. Ottengo degli errori: max
non è dichiarata, numeric_limits non esiste!!
È possibile che il buffer sia infinito?


 È possibile che il buffer sia infinito?
Scusa ma ... pensavo che conoscessi un minimo le librerie di sistema (o che
intuissi che se usi una funzione e/o una classe e il compilatore ti dice che non
e' dichiarata forse e' perche' non hai #incluso il file.
#include <limits>
e se ancora non te la da, usa using namespace std o usa
std::numeric_limits<int>::max()
Per il discorso del buffer infinito ... no, certo. Ma quello specifico valore,
nel contesto di basic_istream::ignore, significa semplicemente "ignora questo
parametro e leggi fino al delimitatore fossero anche 10 terabyte da scartare".


 Andrea Ferro
Beh, sì... che non avevo incluso l'header giusto l'avevo capito: sono
già diversi mesi che programmo in C++!! Ma il prog non funziona
neanche  con #include <limits.h>, nè con tantissime altre soluzioni che
ho provato, anche se, per dirla tutto, sono riuscito a trovarne una, ma
mi sembra troppo forzata. Sicuramente c'è una via più "ortodossa".
Questa questione per me è fondamentale: non credi che la robustezza sia
una caratteristica necessaria in un programma?


 neanche  con #include <limits.h>, 
Infatti l'header da includere per std::numeric_limits
non e' <limits.h>,  ma <limits> senza l'h.
	Mauro

 	Mauro
Ho provato anche questo, ma nulla di diverso. Mi dice che il file non
esiste!!!


 esiste!!!
Mizzega! Quello e' un header standard! Mi sa che non hai un compilatore molto
conforme!



Beh, sě, in effetti il problema dell' header si presenta solo col Dev-C++.
Compilando col bcc32 va bene anche solo #include <limits>, conformemente
allo standard. BTW, ho risolto il problema senza usare
numeric_limits<int>::max()(che, se non erro, ritorna INT_MAX), il cui uso mi
sembra addirittura errato. Questo č il codice che ho scritto:
#include <iostream>
using namespace std;
int main(){
   int n;
  bool flag=0;
......................
....................
  do
  {
      cin.clear();
      if (flag == 1) cin.ignore(256,'\n');
      cout << "Inserisci un intero :";
      cin>>n;
      if (cin.good()) cout << "\nEccolo : "  << n << endl;
      else cout << "Errore !!" << endl;
      flag=1;
  } while (!cin.good());
  cout << "E il prog continua...";
  ...........
 ...........
}
Perň forse si puň fare di meglio. Voglio dire: ho dovuto inserire la
variabile flag per evitare che cin.ignore() venisse eseguita anche la prima
volta. Non credo che questo sia il miglior modo; allora, cos'altro posso
fare?
Dyskolos

 fare?
Perche' non usi l'if che gia' esiste?
   do
   {
       cin.clear();
       cout << "Inserisci un intero :";
       cin>>n;
       if (cin.good())
          cout << "\nEccolo : "  << n << endl;
       else {
          cout << "Errore !!" << endl;
          cin.ignore(256,'\n');
       }
   } while (!cin.good());
   cout << "E il prog continua...";



Dyskolos


Dyskolos

 Così non va!
Vero. Prova cosi':
    for ( bool cingood=false; !cingood; ) {
        cin.clear();
        cout << "Inserisci un intero :";
        cin>>n;
        cingood=cin.good();
        if ( cingood )
            cout << "\nEccolo : "  << n << endl;
        else {
            cout << "Errore !!" << endl;
            cin.ignore(256,'\n');
        }
    }
    cout << "E il prog continua...";



Dyskolos

 96ghq7$qbk$1...@serv1.iunet.it...
Hai il virus del triplo post.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
The instructions said to use Windows 98 or better - so I installed FreeBSD.