PDA

Visualizza la versione completa : [C] Esercizio con acquisizione di strutture e stampa a video


ELY85
21-07-2007, 14:11
TESTO:
Sia dato il file binario "Studenti.dat" (il file esiste) contenente elementi con la seguente struttura:


typedef struct {
int Matricola;
char Nome[20];
char Citta[20];
} Studente;

e sia dato il file binario "Esami.dat" (il file esiste) contenente elementi con la seguente struttura:


typedef struct {
int Matricola;
char Esame[15];
int Voto;
} Esame;

Scrivere un programma C che legga i due file binari, acquisisca da tastiera un nome di città e stampi a video, per ciascun studente della città richiesta, la matricola, il nome, il numero totale di esami sostenuti e la media aritmetica.

ELY85
21-07-2007, 14:12
Ecco il codice del main che ho scritto.
Il problema è che quando ho due studenti della solita città, del primo mi stampa tutti i dati correttamente, del secondo mi stampa correttamente il nome e la matricola, ma gli assegna gli esami e la media del primo studente! Qualcuno può aiutarmi?




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

typedef struct {
int Matr;
char Nome[20];
char Citta[20];
} Studente;

typedef struct {
int Matr;
char Esame[15];
int Voto;
} Esame;


int calcolaMedia (int somma, int esami) {
int media;
if (esami == 1) media = somma;
else media = somma / esami;
return media;
}


int calcolaSomma (int voto) {
int somma;
somma = voto;
return somma;
}



main()
{
FILE *fp;
FILE *f;
Studente s;
Esame e;
char citta[20];
int esami = 0;
int somma = 0;
int media, trovatoEsame = 0;

if ((fp = fopen("Studenti.dat", "rb")) == NULL) {
fprintf(stderr, "Errore di apertura\n");
exit(1);
}
if ((f = fopen("Esami.dat", "rb")) == NULL) {
fprintf(stderr, "Errore di apertura 2\n");
exit(2);
}


printf("Citta da cercare: ");
scanf("%s", citta);



while (fread(&s, sizeof(Studente), 1, fp)>0) {

if (strcmp(citta,s.Citta)==0) {

while (fread(&e, sizeof(Esame), 1, f)>0) {

if (s.Matr == e.Matr) {
trovatoEsame = 1;
do {esami++;} while (s.Matr != e.Matr);
do {somma = somma + calcolaSomma(e.Voto);} while (s.Matr != e.Matr);
media = calcolaMedia(somma, esami); }}
if (trovatoEsame)
printf("%d %s %d %d\n\n", s.Matr, s.Nome, esami, media);
}

}

fclose(fp);
fclose(f);

getch();
}



Dove sbaglio?
GRAZIE MILLE!

ibykos
21-07-2007, 14:27
La fread ha "memoria", ogni volta che la usi su un file aperto, legge il record successivo.
Il primo studente esaurisce tutto il file degli esami, quindi dal secondo studente in poi il while che legge le informazioni sugli esami riceverà EOF ed uscirà subito.
Per risolvere il problema devi aprire e chiudere il file degli esami per ogni studente.
Devi esercitarti di più perché il tuo codice ha parecchie debolezze che si possono eliminare solo con l'esperienza.
Ciao!

ELY85
21-07-2007, 14:39
Come faccio ad aprire e chiudere il file per ogni studente?
Potresti darmi indicazioni su come correggere il mio codice?

GRAZIE MILLE!

ibykos
21-07-2007, 14:45
con un codice simile a questo


while ( per ogni studente){
. fopen
. ...
. while (per ogni esame nel file){
. fread
. }
. ...
. fclose
}

ELY85
21-07-2007, 14:47
Ok...grazie mille!
Vado a provare!
:)

ELY85
21-07-2007, 14:58
Sono già qui!!!! :(


while ( per ogni studente){
. fopen
. ...
. while (per ogni esame nel file){
. fread
. }
. ...
. fclose
}

Qual è il codice delle due condizioni dei due while?
Cioè (per ogni studente) e (per ogni esame nel file)...!
Non devo metterci le fread, vero?

ibykos
21-07-2007, 15:00
Puoi farlo, le condizioni che hai usato nel tuo codice vanno bene.

ELY85
21-07-2007, 15:10
Abbi pazienza....sono proprio dura!!!

Ho modificato così il codice...ma non va bene!!


while (fread(&s, sizeof(Studente), 1, fp)>0) {

if ((f = fopen("Esami.dat", "rb")) == NULL) {
fprintf(stderr, "Errore di apertura 2\n");
exit(2);
}
if (strcmp(citta,s.Citta)==0) {

while (fread(&e, sizeof(Esame), 1, f)>0) {
fread(&e, sizeof(Esame), 1, f);

if (s.Matr == e.Matr) {
trovatoEsame = 1;

do {esami++;} while (s.Matr != e.Matr);
do {somma = somma + calcolaSomma(e.Voto);} while (s.Matr != e.Matr);
media = calcolaMedia(somma, esami);}}

if (trovatoEsame)
printf("%d %s %d %d\n\n", s.Matr, s.Nome, esami, media);
}
fclose(f);
}

fclose(fp);

Non ho capito come lo devo modificare! :bhò: :(

ibykos
21-07-2007, 15:19
Prova riscrivere il programma da capo.
hai notato che questa funzione

int calcolaSomma (int voto) {
int somma;
somma = voto;
return somma;
}
restituisce lo stesso valore che gli passi?
hai notato che in questo frammento di codice

if (s.Matr == e.Matr) {
trovatoEsame = 1;

do {esami++;} while (s.Matr != e.Matr);

la condizione del do è sempre falsa per definizione (si trova in un if che ha la condizione opposta)

Devi riscrivere il codice da capo con tanta pazienza.
Ciao!

P.S. ricordati di inizializzare ed azzerare le variabili che ne hanno bisongo ad ogni ciclo.

Loading