Domanda Aiuto con i file binari C

Stato
Discussione chiusa ad ulteriori risposte.

Fly

Utente Gold
20 Febbraio 2012
852
63
99
286
Ultima modifica da un moderatore:
In prarica dovrei realizzare un programma che creata una struttura dati in grado di memorizzare i voti ottenuti dagli studenti durante l'anno lo inserisca in un file .dat e successivamente tramite una procedura mi stami il voto.

Solo che mi stampa 0.0000 anche se inserisco il voto, questo il codice:

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

struct s_alunno {
char nome[30];
char cognome[30];
float voto;
char materia[30];
};

typedef struct s_alunno var;
int main()
{
    FILE *f1;
    var alunno;
    printf("Inserisci Nome: ");
    scanf("%s", alunno.nome);
    printf("Inserisci Cognome: ");
    scanf("%s", alunno.cognome);
    printf("Inserisci voto: ");
    scanf("%f", &alunno.voto);
    printf("Inserisci materia: ");
    scanf("%s", alunno.materia);
    f1=fopen("voti.dat", "wb");
    if (f1==NULL){
        printf("Impossibile aprire il file\n\n");
        exit(1);
    }
    fwrite(&alunno.nome, sizeof(struct s_alunno), 1, f1);
    fwrite(&alunno.cognome, sizeof(struct s_alunno), 1, f1);
    fwrite(&alunno.voto, sizeof(struct s_alunno), 1, f1);
    fwrite(&alunno.materia, sizeof(struct s_alunno), 1, f1);
    fclose(f1);
    voti();
    return 0;
}

void voti (var alunno){
FILE *f2;
f2=fopen("voti.dat", "rb");
 if (f2==NULL){
        printf("Impossibile aprire il file\n\n");
        exit(1);
    }
fread(&alunno.voto, sizeof(struct s_alunno), 1, f2);
printf("%f", &alunno.voto);
fclose(f2);
}
 
Se il tuo obbiettivo ultimo è quello di memorizzare comunque tutta la struttura dati tanto vale che demandi (correttamente però) tutta l'operazione alla fwrite:
C:
fwrite(&alunno, sizeof(struct s_alunno), 1, f1);
Anche perché nel tuo codice scrivi sempre per la grandezza di struct s_alunno che quindi è errata.
È quindi anche inutile che la funzione voti prenda un parametro, dichiara alunno direttamente all'interno di essa.
La lettura diventa quindi:
C:
fread(&alunno, sizeof(struct s_alunno), 1, f2);
Ricordati anche che, sempre in voti(), stai stampando un float, non il riferimento.

Ci sarebbero altre piccole correzioni da fare volendo ma almeno dovrebbe funzionarti così. Certo che var come alias per struct s_alunno non si può proprio vedere.
 
Io onestamente non riesco a capire cosa c'entri il titolo con il contenuto.
In ogni caso anche la printf finale non è corretta.
 
Il problema è quello segnalato da Scanetatore. Quando poi avrai tanti alunni, se hai usato un array di n elementi ti basterà passare a fread/fwrite l'indirizzo dell'array (il nome dell'array privo di indice) e la dimensione n*sizeof(struct alunno); se invece hai usato una struttura dati allocata dinamicamente (lista, albero, ecc.) dovrai salvare gli alunni uno per uno.
La printf finale non deve prendere l'indirizzo di alunno.voto ma il suo valore (hai scritto "&alunno.voto", devi togliere la &).

Altri consigli sono:
1) evitare typedef insensati;
2) seguire un po' di sane regole di stile;
3) evitare l'uso di scanf (vedi anche i link a fondo pagina);
4) occhio ai buffer overflow: usando scanf per leggere una stringa in input e poi salvarla in un array di char, crei la possibilità che l'utente inserisca più caratteri di quanti ne possa tenere l'array. Se succede, scanf non si ferma alla fine dell'array, ma continua a scrivere nelle aree di memoria successive, sovrascrivendo tutto ciò che trova (e creando un potenziale problema di sicurezza che può portare anche, in applicazioni reali, a una vulnerabilità capace di offrire privilege excalation o anche remote code execution se l'applicazione viene connessa alla rete). Nel tuo caso, prova ad inserire più di 30 caratteri (ad esempio 100) come nome, cognome o materia, e vedi che casino succede.
 
Stato
Discussione chiusa ad ulteriori risposte.