Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
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.
Codice sorgente - presumibilmente C++
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 50
#define num_s 2
typedefstruct{
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,\0), 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,
/* 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);
return0;/* il return non deve mai mancare in int main() */
}
Ultima modifica effettuata da AldoBaldo il 01/02/2022 alle 0:10
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.
A me pare che non ci siano problemi nella scrittura binaria dei dati della struttura.
Probabilmente tu non hai chiaro il significato di file e scrittura binaria. Faresti meglio a studiarli prima da un libro e poi fare esercizi.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
Postato originariamente da AldoBaldo: 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.
Codice sorgente - presumibilmente C++
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 50
#define num_s 2
typedefstruct{
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,\0), 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,
Aprendo in windows con Notepad il file prova.txt, solo l'ultimo dei tre "a capo" dà luogo a un "a capo" effettivamente visibile (quello con la coppia \r\n). I caratteri \n e \r singoli, pur essendo presenti nel file, non danno luogo ad "a capo" visibili.
Altri programmi (ad esempio, WordPad e Notepad++) visualizzano come "a capo" tutti e tre i casi, ma credo siano casi particolari legati al modo in cui sono strutturati. OpenOffice Writer si comporta in modo ancora più strano, saltando a pie' pari una delle tre ripetizioni di "A capo".
Cambiando i requisiti di accesso da "wb" a "w", Notepad visualizza il primo e l'ultimo "a capo" poiché in entrambi compare \n, ma non riconosce come "a capo" il semplice \r. Da notare che Notepad++ in un eccesso di zelo considera \r\n come un DOPPIO "a capo"...
Insomma, meglio non mischiare le due cose. Se vuoi usare fprintf() conviene aprire i file con modalità di accesso testuale; se vuoi usare fwrite() conviene aprire i file con modalità di accesso binaria.
Fai un po' di prove!
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.
Non ha senso usare la fprintf se il file è aperto in binario. A quel punto usa un normale file aperto in modalità testo.
Il binario si usa per gestire velocemente e in maniera più compatta i dati sul file. Si usano le funzioni apposite e NON si può pensare di potere visualizzare o gestire i dati del file binario come se fossero normale testo.
Mi sa che state facendo confusione.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
Appunto. Infatti ho scritto: "Insomma, meglio non mischiare le due cose. Se vuoi usare fprintf() conviene aprire i file con modalità di accesso testuale; se vuoi usare fwrite() conviene aprire i file con modalità di accesso binaria."
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.