Newsgroup: it.comp.lang.c++
Titolo: Un while eseguito una volta di troppo

Qui sotto c'è il file...
è un programma che legge da file la notazione polacca...
es 4 5 + = 4 + 5
4 5 6 + * = (5 + 6) * 4
c'è qualche cout di debug in più ma il programma dovrebbe presentarsi
più o meno così:
-----------------------
#include <iostream>
#include <fstream>
#define MAXNUM 50
using namespace std;
int main()
{
 float numeri[MAXNUM + 1] = {0};
 char nomefile[30] = "";
 char temp[20] = "";
 int cursore = -1;
 ifstream input;
 cout << "Inserisci il nome del file\n";
 gets(nomefile);
 input.open(nomefile);
 if (!input)
 {
  cout << "File non trovato\n";
  system("pause");
  return 1;
 }
 while(!input.eof())
 {
  input >> temp;
  switch (temp[0])
  {
   case '+':
    if (cursore < 1)
    {
     cout << "+Errore nella sintassi del file. Il programma verra'
terminato\n";
     system("pause");
     return 1;
    }
    numeri[cursore - 1] = numeri[cursore - 1] + numeri[cursore];
    numeri[cursore] = 0;
    cursore--;
    cout << numeri[cursore] << " ";
    break;
   case '-':
    if (cursore < 1)
    {
     cout << "-Errore nella sintassi del file. Il programma verra'
terminato\n";
     system("pause");
     return 1;
    }
    numeri[cursore - 1] = numeri[cursore - 1] - numeri[cursore];
    numeri[cursore] = 0;
    cursore--;
    break;
   case '*':
    if (cursore < 1)
    {
     cout << "*Errore nella sintassi del file. Il programma verra'
terminato\n";
     system("pause");
     return 1;
    }
    numeri[cursore - 1] = numeri[cursore - 1] * numeri[cursore];
    numeri[cursore] = 0;
    cursore--;
    break;
   case '/':
    if (cursore < 1)
    {
     cout << "/Errore nella sintassi del file. Il programma verra'
terminato\n";
     system("pause");
     return 1;
    }
    numeri[cursore - 1] = numeri[cursore - 1] / numeri[cursore];
    numeri[cursore] = 0;
    cursore--;
    break;
   default:        
    numeri[cursore + 1] = atof(temp);
    cursore++;
 
  }
 }
 input.close();
 if (cursore =! 0)
 {
  cout << "eErrore nella sintassi. Il programma verra' terminato\n";
  system("pause");
  return 1;
 }
 cout << "Il risultato delle operazioni è " << numeri[0] << endl;    
 system("PAUSE");
 return 0;
}
------------
il programma calcola correttamente i risultati nell'ordine giusto, ma
arrivato alla fine esegue il ciclo while una volta di troppo, vede che
cursore è = a 0, quindi < 1 e visualizza il messaggio d'errore per
quell'operatore. Quindi è come se 4 4 + equivalesse a 4 4 + +. Il
programma calcola 4 + 4, visualizza il risultato giusto e dovrebbe
uscire dal ciclo perchè il controllo del ciclo è un eof sul file, ma
invece esegue ancora il ciclo, e non trovando niente da dare in pasto
a temp (è una mia supposizione) gli lascia il valore del ciclo prima.
cursore sarà = a 0 e quindi viene visualizzato il messaggio d'errore.
Dove sbaglio?
P.S. 
Scusate se è il 2o problema che posto in un giorno... ma non riesco a
trovare l'errore da solo...
---
Membro numero 85 del Luigino Fans Club.
Luigino sei tutti noi!
Anche se ti ho plonkato il tuo ricordo sarà per sempre!

 arrivato alla fine esegue il ciclo while una volta di troppo
provato a controllare con un debugger.
Cosi' su due piedi (non ho avuto tempo di leggere bene il listato) non
riesco a risponderti

 è un programma che legge da file la notazione polacca...
Uno dei possibili errori (forse non l'unico)
potrebbe essere nel ciclo di lettura terminato
con inpunt.eof();
infatti (se le cose stanno come nel C, dove sono piu'
a mio agio) la lettura dell'ultima riga non
fa scattare la segnalazione dell'eof, ma solo
un eventuale tentativo di leggere OLTRE la eof lo fa
scattare.
Quindi per essere sicuro dovresti, per esempio,
mettere un temp[0]=0; subito prima della  input >> temp;
e poi un test su temp[0] subito sotto, cosi' se non
hai letto nulla puoi uscire dal ciclo subito con un break;
L'alternativa "pulita" puo' essere usare un carattere "="
per indicare che bisogna stampare il contenuto
dello stack e uscire, di modo che tutto l'eventuale
contentuto del file dopo la riga con = puo'
essere considerato un commento e non ti devi piu'
preoccupare di linee lette due volte.
ciao,
g.



si grazie così funziona... cmq è strano... possibile che non posso
usare il metodo eof() per i cicli di lettura da file? Tutti gli esempi
lo usano e non fanno certo un ciclo in più. In pratica nel mio
programma potrei tranquillamente mettere while(1), tanto il controllo
eof è inutile. E si che avevo già dei sospetti in questo senso, perciò
dopo input >> temp ho pure scritto un input.get() per essere sicuro di
essere veramente alla fine del file (tanto gli elementi erano separati
da spazi e quindi non rischiavo di cancellare nulla) ma il problema
rimaneva... tra l'altro ho anche trovato un altro errore stronzissimo
(var =! 0) non dà errore di compilazione, ma assegna il valore 1 alla
variabile e ritorna vero (che in effetti è corretto, però è difficile
da trovare).


 da trovare).
di solito errori come questi (un assegnazione durante un test)
vengono segnalati con dei Warning da alcuni compilatori
se selezioni l'opzione
"rompimi le balle con tutti i warning possibili immaginabili".
(tipo -Wall)
Per quell'altra faccenda (eof) non so se c'e' una soluzione
pulita, ma ormai e' un errore che ho fatto tante di quelle volte
in passato che ormai e' la prima cosa che guardo se qualcuno
manda un programma che contiene "eof"....
ciao,
g.



ho inserito -wall come parametro aggiuntivo alla compilazione (uso
devc++ + gcc e adesso quell'istruzione mi dà un warning. Perchè
secondo te un opzione del genere rompe le balle? Può essere utile,
tanto il programma si compila lo stesso e in più ogni tanto puoi dare
una sbirciatina ai warning per vedere se c'è qualche errore...


 una sbirciatina ai warning per vedere se c'č qualche errore...
Stavo solo scherzando.
Il fatto e' che a volte i warning sono cosi' tanti che quelli
importanti possono passare inosservati, almeno questo mi
succedeva col c. Puo' darsi che col c++ molti warning diventano
errori e quindi il problema ha meno rilevanza.
Comunque io di solito li controllo.
ciao.
g.