PDA

Visualizza la versione completa : [C] Aiuto salvataggio matrice su file


sky_451
21-01-2005, 17:59
Ciao a tutti ho un problema che proprio non riesco a capire... :dhò:
ecco il coddice:


#include <stdio.h>
#include <stdlib.h>

int ** alloca_matrice (int righe, int colonne);
void dealloca_matrice(int **matrix, int righe);
void inizializza_matrice (int **matrix, int righe, int colonne);

main ()
{
char *filename = "save.dat";
FILE *fp;
int **matrice = NULL, **matrice2;

matrice = alloca_matrice(6,7);
inizializza_matrice(matrice, 6,7);
matrice2 = matrice;

fp = fopen(filename, "wb");
fwrite(matrice2, sizeof(int), 42, fp);
fclose(fp);

dealloca_matrice(matrice, 6);

fp = fopen(filename, "rb");
fread(matrice2, sizeof(int), 42, fp);
fclose(fp);

printf("\n\t%d\n", matrice2[0][0]);

return 0;
}

int ** alloca_matrice (int righe, int colonne)
{
int **matrix, i;

if(!(matrix= (int **) malloc (righe * sizeof(int *))))
return(NULL);

for (i=0; i<righe; i++)
{
if(!(matrix[i]= (int *) malloc(colonne * sizeof(int))))
return(NULL);
}
return(matrix);
}

void dealloca_matrice(int **matrix, int righe)
{
int i=0;

for(i=0; i<righe; i++)
{
free(matrix[i]);
}

free(matrix);
}

void inizializza_matrice (int **matrix, int righe, int colonne)
{
int i, j;

for (i=0; i<righe; i++) {
for (j=0; j<colonne; j++) {

matrix[i][j]= 0;
}
}
}


il problema è che dopo aver deallocato matrice, quando vado a caricare da file quello che avevo salvato e lo metto su matrice2 la printf finale mi stampa un numero tipo -1233242345. In pratica in matrice2 non mi si salva quello che io salvo su file.
Sto andando fuori di testa per questo problema :dottò: .
Grazie.

sky_451
21-01-2005, 18:50
up!
nessuno ha qualche idea? :cry:

Insaponata
21-01-2005, 22:38
Guarda sinceramente mi scoccio di leggere tutto il codice... cmq quando ti escono sti numeri strani vuole dire che hai sbagliato qualcosa coi puntatori.

sky_451
22-01-2005, 00:08
cmq le tre funzioni:
int ** alloca_matrice (int righe, int colonne);
void dealloca_matrice(int **matrix, int righe);
void inizializza_matrice (int **matrix, int righe, int colonne);

sn già tutte state testate e funzionano, mi sono solo servite per provare questo programma "test". La scocciatura, quindi, sta nel leggere il solo main e in particolare quando richiamo dealloca_matrice, che a quanto pare mi crea il problema che ho già detto.

anx721
22-01-2005, 14:37
Ci sono due errori:

- il primo è che non allochi soazio per matrice2, ma matrice2 la fai puntare a matrice, pero prima di leggere deallochi matrice, quindi matrice2 punta a memoria deallocata; il modo correto di procedere e di allocare spazio indipendente per matrice2;

- il secondo errore è nelle fwrite e nelle fread, perchè passi un puntatore da cui leggere o in cui scrivere, e dai come dimensione 42, ma matrice e matrice2 non sono un array lineare in cui ci sono tutti i 42 elementi in fila, ma sono dei puntatori a puntatori, ogni riga delle matrici è stata allocata separatamente, quindi i 7 elementi della rima riga stanno in una porzione di memoria, i 7 elementi della seconda riga stanno in un altra porzione di memoria, non puoi semplicemente passare il puntatore alla prima riga perche i 42 elementi non sono tutti a partire da li. Difatti fread e fwrite vogliono come argomento un void*, mtnre tu passi un puntatore a puntatre; morale della favola le righe vanno scritte e lette separatamente.



#include <stdio.h>
#include <stdlib.h>

int ** alloca_matrice (int righe, int colonne);
void dealloca_matrice(int **matrix, int righe);
void inizializza_matrice (int **matrix, int righe, int colonne);
void stampa_matrice(int **matrix, int righe, int colonne);

int main ()
{
char *filename = "save.dat";
FILE *fp;
int **matrice = NULL, **matrice2;

matrice = alloca_matrice(6,7);
inizializza_matrice(matrice, 6,7);
matrice2 = alloca_matrice(6,7);;
printf("Matrice originaria:\n\n");
stampa_matrice(matrice, 6, 7);
fp = fopen(filename, "wb");
int i;
for(i = 0; i < 6; i++)
fwrite(matrice[i], sizeof(int), 7, fp);
fclose(fp);
dealloca_matrice(matrice, 6);
fp = fopen(filename, "rb");
for(i = 0; i < 6; i++)
fread(matrice2[i], sizeof(int), 7, fp);
fclose(fp);
printf("\n\nMatrice letta da file:\n\n");
stampa_matrice(matrice2, 6, 7);
dealloca_matrice(matrice2, 6);
return 0;
}

int ** alloca_matrice (int righe, int colonne)
{
int **matrix, i;

if(!(matrix= (int **) malloc (righe * sizeof(int *))))
return(NULL);

for (i=0; i<righe; i++)
{
if(!(matrix[i]= (int *) malloc(colonne * sizeof(int))))
return(NULL);
}
return(matrix);
}

void dealloca_matrice(int **matrix, int righe)
{
int i=0;

for(i=0; i<righe; i++)
{
free(matrix[i]);
}

free(matrix);
}

void inizializza_matrice (int **matrix, int righe, int colonne)
{
int i, j;

for (i=0; i<righe; i++) {
for (j=0; j<colonne; j++) {

matrix[i][j]= 0;
}
}
}

void stampa_matrice(int **matrix, int righe, int colonne){
int i, j;
for(i = 0; i < righe; i++){
for(j = 0; j < colonne; j++)
printf("%d ", matrix[i][j]);
printf("\n");
}
}

sky_451
23-01-2005, 02:26
Grazie mille. Adesso mi studio bene tutto quello che mi hai detto, cmq mi hai dato una grossa mano, grazie ancora.
:ciauz:

sky_451
23-01-2005, 12:58
Ora ho un altro problema: :D
ecco il codice:


// Dichiarazione della struttura contenente le info per il salvataggio
struct Salvataggio
{
int **matrix;
int righe;
int colonne;
char giocatore1[20];
char giocatore2[20];
};

int salva_partita (int **matrix, int righe, int colonne, char *giocatore1, char *giocatore2)
{
char *filename = "save.dat";
FILE *fp;
int vero=TRUE, falso=FALSE;
struct Salvataggio *salvataggio;

salvataggio = (struct Salvataggio *) malloc(sizeof(struct Salvataggio)); // alloco la memoria per una struct Salvataggio

/* Salvo tutti i valori nei rispettvi campi della struttura */
salvataggio->matrix = alloca_matrice(righe, colonne); // alloco memoria per la matrice della struttura in cui salverò la matrice originale
copia_matrice(salvataggio->matrix, matrix, righe, colonne); // copio la matrice originale nella matrice della struttura
salvataggio->righe = righe;
salvataggio->colonne = colonne;
strcpy(salvataggio->giocatore1, giocatore1);
strcpy(salvataggio->giocatore2, giocatore2);

if((fp = fopen(filename, "wb")) == NULL) // apro il file binario in scrittura
return falso; // se il file non si apre correttamente la funzione termina

if(fwrite(salvataggio, sizeof(struct Salvataggio), 1, fp) != 1) // salvo la struct Salvataggio nel file
{
fclose(fp); // se la scrittura non avviene correttamente
return falso; // chiudo il file e la funzione termina
}

fclose(fp); // chiudo il file
return vero;
}

Dopo che faccio il salvataggio di una struttura di questo tipo in cui salvo le info che passo come parametri alla funzione salva_partita, come posso crearmi una funzione per caricare quello che ho salvato sul file in un'altra struct Salvataggio?
Il problema sta nel fatto che non so come fare ad allocare spazio per il campo **matrix della struct in cui salverò i dati letti dal file. Non riesco a fare questo per il semplice fatto che ancora non conosco il valore di righe e colonne che devo anch'essi leggere dal file. Magari è possibile leggere i campi separatamente?
Grazie per l'aiuto.

anx721
23-01-2005, 14:07
Quello che farei io è:

In scrittura scriverei singolarmente il numero di righhe, il numero di colonne, e le varie righe della matrice:



fwrite(salvataggio -> righe, sizeof(int), 1, fp)
fwrite(salvataggio -> colonne, sizeof(int), 1, fp)


Poi scrivi le righe che vanno scritte una per una come gia ti ho detto, non scrivendo l'intera struct nel file: devi capire che la struct non contiene le righe, ma solo il puntatore alle rgihe: scrivendo la struct scrivi semplicemente tale puntatore, non i valori delle righe; per scrivere le righe devi fare il for come ti ho detto.


per leggere:



Salvataggio *s = (struct Salvataggio *) malloc(sizeof(struct Salvataggio));
//leggo il numero di righe
fread(&(s -> righe), sizeof(int), 1, fp);
//leggo il numero di colonne
fread(&(s -> colonne), sizeof(int), 1, fp);
//ora posso allocare la matrice
s -> matrix = alloca_matrice(s -> righe, s -> colonne);
//ora leggi le righe una ad una come gia ti ho fatto vedere


Inoltre non c'è bisogno di copiare la struttura su un altra prima di scriverla.

sky_451
23-01-2005, 18:37
ok ora ho capito.
Spero di riuscire a risolvere.
Grazie ancora.
:ciauz:

sky_451
23-01-2005, 18:47
ma se faccio queste due istruzioni:

fwrite(salvataggio -> righe, sizeof(int), 1, fp)
fwrite(salvataggio -> colonne, sizeof(int), 1, fp)

ho un warning, in quanto il primo parametro della fwrite è un void* e invece io così non passo un puntatore.
Non devo tenerne conto?

Loading