Ok perfetto ora va.
Comunque utilizzo CodeBlocks 20.03
Quello però è l'IDE, non è il compilatore.
@DispatchCode Ora potrei chiederti una cosa?
C:
void putStruct(studenti *stud1, FILE *pf);
Questa é il prototipo della procedura (se non sbaglio). Vorrei capire il perche abbiamo messo quelle cose tra le parentesi. So che sono uno il puntatore a stud1 e l'altro il puntatore a pf, ma perche é cosi?
Si, il prototipo della funzione è la
dichiarazione della funzione. Quando invece vai a scrivere il codice al suo interno, dove usi le parentesi graffe, allora la stai
definendo.
In merito alla seconda domanda:
C:
void putStruct(studenti *stud1, FILE *pf)
Questo è il prototipo della funzione: vale a dire che stai dicendo che la funzione accetta due parametri, uno è un puntatore a una struct di tipo studenti (o meglio, il cui alias è studenti) e l'altro è un puntatore a FILE.
Puoi anche non specificare il nome (mi riferisco a stud1 e pf), è irrilevante. Quello che conta è il tipo.
C:
void putStruct(studenti *stud1, FILE *pf)
{
}
Quindi la funzione segue quanto indicato dal prototipo. Qui stud1 e pf sono variabili locali alla funzione (esistono solo qui dentro, al termine della funzione, non puoi più utilizzarle, perchè non esistono).
Questo é invece il richiamo della procedura dentro il main. Ma anche qui ti chiedo il perche di quelle cose tra le tonde...
Considerando che la funzione accetta due parametri del tipo visto in precedenza, quando la chiami, dovrai passare un indirizzo di memoria di tipo "studenti" e un puntatore a FILE.
Ora, penso che il tuo dubbio sia "perchè usare una
& quando come parametro c'è
*?".
La risposta è semplice: la funzione ha come parametro un puntatore a studenti e un secondo parametro, che è un puntatore a FILE.
Queste due variabili sono dichiarate in questo modo:
C:
studenti stud1;
FILE *pf;
quindi una è una variabile chiamata stud1 di tipo studenti (che è una struct), e l'altra è un puntatore a FILE. Quindi, passandoli alla funzione vista prima, dovrai passare l'indirizzo di stud1 (che viene memorizzato in un puntatore) e "pf", che è già un puntatore.
Faccio notare che la "stud1" vista nel main
non è la "stud1" presente nelle funzioni. Si tratta di variabili diverse, in quanto hanno scope differenti: si tratta di due variabili che hanno il nome uguale nel tuo codice sorgente, ma sono in realtà due indirizzi (locazioni) diverse di memoria.
Ora posso spiegarati perchè ti ho detto di usare un puntatore qui:
C:
void printStruct(studenti *stud1, FILE *pf)
{
fread(stud1,sizeof(stud1),1, pf);
}
Considera sempre il codice di prima, rivisto, togliendo i puntatori a studenti:
C:
#include <stdio.h>
typedef struct {char nome[20];
char cognome[20];
char codFiscale[20];
int anni;
char sesso;
}studenti;
void putStruct(studenti, FILE *pf);
void printStruct(studenti, FILE *pf);
int main()
{
studenti stud1;
FILE *pf;
printf("Inserire il nome: ");
scanf("%s",stud1.nome);
printf("Inserire il cognome: ");
scanf("%s", stud1.cognome);
printf("Inserire il codice fiscale: ");
scanf("%s", stud1.codFiscale);
printf("Inserire l'eta: ");
scanf("%d", &stud1.anni);
printf("Inserire il sesso: ");
scanf(" %c", &stud1.sesso);
pf=fopen("Archivio.txt", "w");
if(pf)
{
putStruct(stud1, pf);
fclose(pf);
}
else
{
printf("Errore.");
}
pf=fopen("Archivio.txt", "r");
if(pf)
{
printStruct(stud1, pf);
printf("%s\n", stud1.nome);
printf("%s\n", stud1.cognome);
printf("%s\n", stud1.codFiscale);
printf("%d\n", stud1.anni);
printf("%c\n", stud1.sesso);
fclose(pf);
}
else
{
printf("Errore.");
}
return(0);
}
void putStruct(studenti stud1, FILE *pf)
{
fwrite(&stud1,sizeof(stud1),1, pf);
}
void printStruct(studenti stud1, FILE *pf)
{
fread(&stud1,sizeof(stud1),1, pf);
stud1.anni = 123;
}
Come noti ho forzato l'età a 123 nella funzione printStruct.
Eseguendolo ottengo questo:
Codice:
Inserire il nome: nome
Inserire il cognome: cognome
Inserire il codice fiscale: sdfg
Inserire l'eta: 98
Inserire il sesso: n
nome
cognome
sdfg
98
n
Perchè l'età non è 123?
Eseguendo l'altra versione, ma mantenendo la modifica sugli anni in questo modo:
C:
void printStruct(studenti *stud1, FILE *pf)
{
fread(stud1,sizeof(stud1),1, pf);
stud1->anni = 123;
}
si ottiene:
Codice:
Inserire il nome: nome
Inserire il cognome: cognome
Inserire il codice fiscale: asdf
Inserire l'eta: 987
Inserire il sesso: m
nome
cognome
asdf
123
m
Perchè questo? Proprio perchè stiamo usando un puntatore. Grazie al puntatore la "stud1" della funzione accede al medesimo indirizzo di memoria della "stud1" presente nel main, e in questo modo puoi alterare il valore di un membro e mantenere la modifica anche fuori (ovvero nel main).
Ci sarebbe altro da precisare, ma preferisco non aggiungere altro, per non farti fare confusione (a meno di tue domande specifiche, ovviamente).