A parte un paio di errori con scanf(), il problema del testo in uscita "pasticciato" nasce dalla differenza tra fopen() usato con attributo d'accesso testuale o binario e dall'uso di fwrite() in luogo di fprintf().
Se apri un file con accesso binario il carattere '\n' viene preso alla lettera e in windows e in macintosh non dà un vero "a capo" (in macintosh l'"a capo" è \r, mentre in windows è \r\n).
Se usi fwrite(), scrivi sul file sempre alla lettera e byte per byte TUTTO quello che c'è nello spazio di memoria puntato dal primo parametro. Siccome dichiari la struttura studente con due buffer da 50 caratteri ciascuno, ad ogni scrittura vengono scritti su file TUTTI i 100 caratteri più i byte occupati dall'intero successivo. Se in un campo da 50 char ne hai impostato solo alcuni, quelli non impostati vengono comunque scritti alla lettera con il loro contenuto casuale.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 50
#define num_s 2
typedef struct{
char nome[max];
char cognome[max];
int voto;
} struttura;
int main() {
struttura studente; /* qui il contenuto di studente e' indeterminato */
int i;
FILE *f;
if((f=fopen("archivio.txt", "wb"))==NULL){
printf("errore nell'apertura del file!");
exit(0);
}
for(i=0;i<num_s; i++){
printf("Studente n %d:\n", i+1);
printf("\nNome: ");
scanf("%s", studente.nome); /* era scanf("%s", &studente.nome); */
printf("\nCognome: ");
scanf("%s", studente.cognome); /* era scanf("%s", &studente.cognome); */
printf("\nVoto: ");
scanf("%d", &studente.voto);
fwrite(&studente, sizeof(struttura), 1, f);
/* Con fwrite() scrivi nel file non soltanto le stringhe e i valori
** appena immessi, ma anche tutto il contenuto ancora indeterminato
** di parte dei campi nome e cognome se il nome e' "mario", hai
** inserito in studente.nome sei caratteri (m,a,r,i,o,A parte un paio di errori con scanf(), il problema del testo in uscita "pasticciato" nasce dalla differenza tra fopen() usato con attributo d'accesso testuale o binario e dall'uso di fwrite() in luogo di fprintf().
Se apri un file con accesso binario il carattere '\n' viene preso alla lettera e in windows e in macintosh non dà un vero "a capo" (in macintosh l'"a capo" è \r, mentre in windows è \r\n).
Se usi fwrite(), scrivi sul file sempre alla lettera e byte per byte TUTTO quello che c'è nello spazio di memoria puntato dal primo parametro. Siccome dichiari la struttura studente con due buffer da 50 caratteri ciascuno, ad ogni scrittura vengono scritti su file TUTTI i 100 caratteri più i byte occupati dall'intero successivo. Se in un campo da 50 char ne hai impostato solo alcuni, quelli non impostati vengono comunque scritti alla lettera con il loro contenuto casuale.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 50
#define num_s 2
typedef struct{
char nome[max];
char cognome[max];
int voto;
} struttura;
int main() {
struttura studente; /* qui il contenuto di studente e' indeterminato */
int i;
FILE *f;
if((f=fopen("archivio.txt", "wb"))==NULL){
printf("errore nell'apertura del file!");
exit(0);
}
for(i=0;i<num_s; i++){
printf("Studente n %d:\n", i+1);
printf("\nNome: ");
scanf("%s", studente.nome); /* era scanf("%s", &studente.nome); */
printf("\nCognome: ");
scanf("%s", studente.cognome); /* era scanf("%s", &studente.cognome); */
printf("\nVoto: ");
scanf("%d", &studente.voto);
fwrite(&studente, sizeof(struttura), 1, f);
/* Con fwrite() scrivi nel file non soltanto le stringhe e i valori
** appena immessi, ma anche tutto il contenuto ancora indeterminato
** di parte dei campi nome e cognome se il nome e' "mario", hai
** inserito in studente.nome sei caratteri (m,a,r,i,o,{parsed_message}), ma i 44
** successivi rimangono com'erano al momento della dichiarazione
** della variabile struttura studente, cioe' indeterminati, e vengono
** scritti tali e quali nel file. Per i campi successivi valgono
** analoghe considerazioni. */
/* Se vuoi che il file sia correttamente leggibile, usa fprintf()
** (nota: siccome il file e' stato aperto con attributi binari e non
** testuali, per ottenere l'a capo in windows occorre usare \r\n,
** non solo \n) */
/*
fprintf(f,"%s %s %d\r\n",studente.nome,studente.cognome,studente.voto);
*/
/* volendo usare solo \n come carattere di "a capo" in fprintf() avresti
** dovuto aprire il file con attributo d'accesso "w", non "wb" */
/*
fopen("archivio.txt", "w"); // alla riga 19
*/
}
fclose(f);
return 0; /* il return non deve mai mancare in int main() */
}
), ma i 44
** successivi rimangono com'erano al momento della dichiarazione
** della variabile struttura studente, cioe' indeterminati, e vengono
** scritti tali e quali nel file. Per i campi successivi valgono
** analoghe considerazioni. */
/* Se vuoi che il file sia correttamente leggibile, usa fprintf()
** (nota: siccome il file e' stato aperto con attributi binari e non
** testuali, per ottenere l'a capo in windows occorre usare \r\n,
** non solo \n) */
/*
fprintf(f,"%s %s %d\r\n",studente.nome,studente.cognome,studente.voto);
*/
/* volendo usare solo \n come carattere di "a capo" in fprintf() avresti
** dovuto aprire il file con attributo d'accesso "w", non "wb" */
/*
fopen("archivio.txt", "w"); // alla riga 19
*/
}
fclose(f);
return 0; /* il return non deve mai mancare in int main() */
}
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.