PDA

View Full Version : [C++] Problema stranissimo, risultati sballati a volte


ciuaz!!!
02-02-2008, 16:24
#include <iostream>
#include <fstream>
using namespace std;

void F(int *X, int &q, int &w, int &e)

{
ifstream IN("input");
ofstream OUT ("output");
if(!IN || ! OUT)
throw (0);

int cont=0;


for (int i=0; (i<80) && (!IN.eof()); i++){
IN>>X[i];
cont++;
}


if (IN.eof()) cont--;
q=cont/20; //numero di torte (ciascuna contiene 20 elementi
w=(cont%20)/5; //numero di righe (ogni riga contiene 5 elementi)
e=((cont%20)%5); // numero di elementi rimanenti

IN.close();

}

int main()
{
try {
ifstream IN ("input");
ofstream OUT("output");

int A[4][4][5];
int indice1=0,indice2=0,indice3=0;
int *p= &A[0][0][0];
int numeroelementi;
F(**A, indice1, indice2, indice3);

OUT << indice1 << ' ' << indice2 << ' ' << indice3 << ' ';

numeroelementi= indice1*20 + indice2*5 + indice3;

for (int i=0; i<numeroelementi; i++)
OUT<<*(p+i)<<' ';

IN.close();
OUT.close();

}
catch(int x) {cout<<"problemi con i file"<<x<<endl;}
}

Sto impazzendo. Questo programmetto per l'università prende da un file input una sequenza di interi con uno spazio che li divide e uno spazio alla fine della sequenza (per esempio 1 2 3 4 5 6 7 8 9 0 ). Poi mette in output 3 indici che fanno capire come è stato riempito l'array a 3 dimensioni, e in seguito stampa gli elementi dell'array che sono stati messi in input.

Il problema è che a volte mi dà in output strani caratteri indecifrabili (questi ′‰‰‱′″‴‵‶‷‸‹‰‱′″‴‵‶‷‸‹‰), faccio girare nuovamente il programma e in output mi dà sempre la stessa sequenza 4 0 0 2089314996 2089305984 [...] (ovviamente sballata e totalmente indipendente da quello che scrivo in input).

Devo quindi cancellare il file input e farne un altro, il programma funziona di nuovo per alcune sequenze (tipo 7 8 54 43 6 6 7 3 ) ma non funziona con 40 elementi, 39 elementi, 80 elementi... mentre con 20 elementi funziona (1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ).

Non riesco proprio a capire perchè, faccio "a mano" le operazioni e non vedo errori.

Vi prego una mano, prima che spacchi tutto...:asd: (è rimasta integra ancora la tastiera e il monitor).

cionci
03-02-2008, 09:11
if(!IN || ! OUT)
throw (0);

La gestione degli errori sui file è completamente errata. Sia quella sopra che il blocco try-catch, visto che non vengono generate eccezioni.

Inoltre è sbagliato il passaggio dei parametri alla funzione F...ma non sbagliato soltanto, è proprio orrido :D

Cosa volevi passare a F ?

ciuaz!!!
03-02-2008, 09:30
if(!IN || ! OUT)
throw (0);

La gestione degli errori sui file è completamente errata. Sia quella sopra che il blocco try-catch, visto che non vengono generate eccezioni.

Inoltre è sbagliato il passaggio dei parametri alla funzione F...ma non sbagliato soltanto, è proprio orrido :D

Cosa volevi passare a F ?

:cry: è il mio primo mese di C++.

Alla funzione gli passo F(**A, indice1, indice2, indice3) con **A il puntatore al primo elemento dell'array A[4][4][5]. Ma fai conto che abbia scritto &A[0][0][0] al posto di **A.
Poi passo indice1 2 3, perchè è sbagliato? :confused:
Ho dichiarato nella funzoine int &q, int &w, int &e che sono alias di indice1, indice2, indice3... (edit: più precisamente, nello specifico int &q, ecc.. sono i parametri formali, poi quando la F viene invocata, all'interno della funzione sono creati gli alias di indice1,2,3)

Avrei forse dovuto scrivere così?


int &F (int *X, &q, &w, &e)

?

Per il try / catch sono in alto mare, se ricordi dalla volta scorsa è il prof che ci ha scritto quella parte di programma, io da quella volta copio/incollo il try catch.
Non saprei proprio come gestirlo.

cionci
03-02-2008, 09:49
Te l'avevo scritto come si gestiscono gli errori nei file l'altra volta.
Se IN.fail() è vero allora hai un'errore ;) Se è falso puoi continuare l'esecuzione.
Comunque ho letto male, in effetti va bene il passaggio, non avevo visto che era un vettore a tre dimensioni.

Quindi il passaggio dei parametri è corretto. Magari è proprio la gestione degli errori sul file che non funziona ?

Prova a mettere:

ifstream IN("input");
if(IN.fail()) throw 0;

al posto di:

ifstream IN("input");
ofstream OUT ("output");
if(!IN || ! OUT)
throw (0);

Togli inoltre

ifstream IN("input");
ofstream OUT ("output");

dal main (nota che il file di out non ti serve).

ciuaz!!!
03-02-2008, 09:59
Ok grazie mille cionci, ora provo.

Edit: Allora... non va.Ho fatto quello che mi hai consigliato, con l'unica eccezione del main: lì ho tolto solo ifstream IN, perchè a me serve scrivere in un file di output (è la consegna dell'esercizio, e serve, immagino, per la correzione automatica dello stesso).
Tirando le somme credo proprio tu abbia ragione, cioè il problema è la gestione degli errori.

void F(int *X, int &q, int &w, int &e)

{
ifstream IN("input");
if(IN.fail()) throw 0;

e qua non mi sembra ci siano problemi, legge dal file "input", se la lettura fallisce --->throw(0).
PS:magari dico una cazzata ma prima di ifstream ecc... ci va il try?

[CORPO FUNZIONE]

IN.close(); //chiude il file input, anche qua non mi sembra ci siano problemi.

int main()
{
try {
ofstream OUT("output"); // l'output s'ha da scrivere nel file "output".

[CORPO MAIN]
OUT << indice1 << ' ' << indice2 << ' ' << indice3 << ' '; //scrive in output i 3 indici (a volte va a volte no)... che ci sia qualcosa che non va? Ho notato che con 80 interi non funziona, con 20 si, con 90 no ... mah.

OUT.close(); //chiude il file di output

}
catch(int x) {cout<<"problemi con i file"<<x<<endl;} //boh.
}

sottovento
03-02-2008, 18:43
Prova a cambiare nome alle variabili rappresentanti i file: IN e OUT sono gia' definite in alcuni compilatori.
Inoltre non aprire due volte i file: una basta.

Ciao

ciuaz!!!
04-02-2008, 10:02
Sotto Linux funziona bene, non da' errori di alcun tipo. Mah...
E visto che il mio prof usa Linux il problema e' risolto :asd:
Un Grazie per i preziosi consigli a cionci e sottovento.