Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 22
  1. #1

    [c] problema lettura di un file binario

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct persona {
    	int numero ;
    	char *nome ;
    	char cognome [6] ;
    } ;
    
    typedef struct persona persona ;
    
    int main ()
    
    
    {
       FILE *Jtr ;
    
       persona persona ;
        
    	if ( (Jtr = fopen ("persona.dat" , "wb" ) ) != NULL )
    
    	{
    
            /* inizializzo la struttura */
    
    	persona.numero = 1 ;
    	persona.nome = "tony" ;
    	gets (persona.cognome) ;
    
    
            fwrite (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    	fprintf (stdout , "%s\n" , persona.nome ) ;
    	}
      
    
    
    	fclose (Jtr ) ;
    	system ("PAUSE") ;
    
    	return 0 ;
    }

    quando vado per leggerla con questo codice :


    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct persona {
    	int numero ;
    	char *nome ;
    	char cognome [6] ;
    } ;
    
    typedef struct persona persona ;
    
    int main ()
    
    
    {
    	
       FILE *Jtr ;
    
        persona persona ;
    
    
        
    	if ( (Jtr = fopen ("persona.dat" , "rb" ) ) != NULL )
    	{
    
    	fread (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    
    	fprintf (stdout , "%d%s\n" , persona.numero , persona .cognome   ) ;
            fprintf (stdout , "%s\n", persona .nome   ) ; /* questa e la riga che mi crea problemi */
    	
    
    	}
      
    
    
    	fclose (Jtr ) ;
    	system ("PAUSE") ;
    
    	return 0 ;
    }
    mi da errore di allocazione della memoria ;

    qualcuno sa spiegarmi il perchè ?
    grazie

  2. #2
    codice:
    struct persona {
    int numero ;
    char *nome ;
    char cognome [6] ;
    } ;
    Questa struttura ha un problema.
    Il campo nome non è un array statico di char, ma è un puntatore, quindi lo devi inizializzare con malloc o crearne uno statico con char nome[dimensione]

    codice:
    persona.nome = "tony" ;
    Nella lettura t'è andata bene, perchè ogni stringa che scrivi, viene allocata nella string table dell'eseguibile, quindi hai copiato l'indirizzo della stringa in quello di nome, ma nel momento in cui passi un array non allocato a fread ti da errore di allocazione.

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,318

    Moderazione

    Prendi visione del Regolamento interno, per conoscere le norme di partecipazione al forum.

    In particolare, il codice va postato indentato e all'interno degli appositi tag CODE.

    Sistemo io.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4
    ciao ti ringrazio molto , ma ancora non capisco del tutto il problema


    ho provato a modificare così


    codice:
    
                    .............................................
                    fread (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    		persona.nome = (char*) malloc ( sizeof (char) * 6 ) ;
    		 
    		fprintf (stdout , "%s\n" , persona .cognome   ) ;
                    fprintf (stdout , "%s\n", persona .nome   ) ;
    .................................

    ma mi visualizza a schermo tutto fuorchè la stringa che avevo creato
    dov'è che sbaglio?
    grazie

  5. #5
    Originariamente inviato da toni00c
    ciao ti ringrazio molto , ma ancora non capisco del tutto il problema


    ho provato a modificare così


    codice:
    
                    .............................................
                    fread (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    		persona.nome = (char*) malloc ( sizeof (char) * 6 ) ;
    		 
    		fprintf (stdout , "%s\n" , persona .cognome   ) ;
                    fprintf (stdout , "%s\n", persona .nome   ) ;
    .................................

    ma mi visualizza a schermo tutto fuorchè la stringa che avevo creato
    dov'è che sbaglio?
    grazie
    l'allocazione la devi fare prima.

    o cambi la struttura così

    codice:
    struct persona { int numero ; char nome[10] ; char cognome [6] ; } ;
    oppure prima di fread fai malloc

  6. #6
    ciao ti ringrazio molto per il chiarimento , ma nel mio programma c'è qualcosa che non va
    nella prima parte ho dichiarato e inizializzato nella struct un puntatore a una stringa
    e creato un file di nome Persona.txt

    codice:
    persona.nome = "tony" ;

    in un programma separato di lettura ho inizializzato la memoria prima di fread , ma
    il risultato è il medesimo errore ;

    codice:
    if ( (Jtr = fopen ("persona.txt" , "rb" ) ) != NULL )
    	{
    
    		
    
    	        persona.nome = (char*) malloc ( sizeof (char) * 10 ) ;
    		fread (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    		
    		
    	
    		
    		 
    		fprintf (stdout , "%s\n" , persona .cognome   ) ;
            fprintf (stdout , "%s\n", persona .nome   ) ;
    	
    }
      .......................................


    "Unhandled exception at 0x6514984f (msvcr90d.dll) in lettura.c.exe: 0xC0000005: Access violation reading location 0x00f55758"

    ma dove può essere l'errore?

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    L'errore è qui:
    codice:
    struct persona {
    	int numero ;
    	char *nome ;
    	char cognome [6] ;
    } ;
    cioè che usi un puntatore e poi serializzi la struttura.
    Quando vai a scrivere, non scrivi il contenuto di nome, ma il valore del puntatore.
    Allo stesso modo quando vai a leggere, assegni a quel puntatore 4 bytes presi nel file che non sono quelli che vorresti. E tutto questo è indipendente da una allocazione tramite malloc.
    Se vuoi serializzare la struttura con:
    codice:
    fwrite (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    fread (&persona  , sizeof (struct persona  ) , 1 ,  Jtr ) ;
    quel campo deve avere dimensione fissa.
    codice:
    struct persona {
    	int numero ;
    	char nome[10] ;
    	char cognome [6] ;
    } ;

  8. #8
    ciao ti ringrazio molto , finalmente ho capito !

    una chiarezza estrema

    ma ho un ulteriore domanda che penso possa essere interessante :


    codice:
    
    struct titolo {
    	int codTitolo ;
    	float ap ;
    	float ch ;
    	float valore ;
    } ;
    
    typedef struct titolo titolo ;
    typedef titolo *titoloPtr ;
    
    int main ()
    
    {
    
    	FILE *Ptr ;
    
    	titoloPtr result ;
    	int codTitoli [10] = { 22 , 12 , 10 , 10 , 22 , 12 , 15  , 30 ,    30 ,  15 } ;
    	float valori [10]  = { 100 , 202.2 , 300.2 , 123.4 , 21.22 , 124.66 , 938.34 , 42.3 , 333.4 , 1.25 } ;
    	int dim = 10 ;
    	int i ;
    	int j ;
    	int b ;
    	int resultDim  = 0 ;
    	int key   ;
    
    
    
    	result = (titolo*)  malloc (sizeof (struct titolo ) * (dim/2) ) ;
    
    
    
    ............................................................
    
    
    if ((Ptr =fopen ("titolo.txt" , "wb") ) != NULL )
    
    {
    	for ( b = 0 ; b < resultDim ; b++)
    		fwrite ( &result , sizeof ( struct titolo ) , 1 , Ptr ) ;
    }
    
    .......................


    in questo caso scrivo un vettore di dimensione ( dim/2) dinamico sul file "titolo.txt" ;

    presumo che andrei incontro allo stesso identico problema non è vero?

    Insomma chiariamo una volta per tutte cosicchè anche altre persone possano trarre giovamente da questo topic :

    posso scrivere "dati di dimensione dinamica" per poi successivamente leggerli ?

  9. #9
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Alla fine puoi scrivere qualsiasi tipo di dato,purchè dopo tu sappia come leggerli.
    Un metodo è quello di utilizzare un carattere di riconoscimento per separare tutti gli elementi.
    Altrimenti devi sapere la dimensione.
    Comunque è quello che fai tutte le volte che usi funzioni come scanf o printf,in fondo queste funzioni leggono finchè non trovano il carattere newline,che inserisci premendo invio.
    Alla fine almeno per scelta personale io non mi preoccuperei tanto di come scrivere i dati sul file,tanto in qualsiasi tipo di dato,che sia un float o un carattere non inconterai mai difficoltà se ha cifre variabili,basta che sai quando smettere di leggere,cioè quando incontri il carattere separatore.
    Le funzioni come fwrite e fread le uso solo per leggere una gran quantità di elementi più velocemente,per il resto ho la funzione apposita per leggere da file e allocare dinamicamente l' array.

  10. #10
    La faccenda è questa:

    codice:
    size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
    fread non conosce il formato del buffer che gli passi. Lui vede quel buffer solamente come un insieme di size bytes.

    La funzione legge tot byte dal file e copia byte-byte il buffer letto nel buffer che gli passi.

    Se tu passi una struttura de genere:

    codice:
    struct anag {
        char* nome;
        char cognome[10],
    };
    anche se poi allochi nome quel char* nome è sempre una variabile long (ovvero mantiene in se un indirizzo di memoria di 4 byte) e quella struttura è quindi di 14 byte.

    Se tu scrivi sul file questa stringa "Dante Alighieri", quando l'andrai a leggere con fread in quella struttura, la funzione scriverà byte per byte, quindi avrai una struttura danneggiata che conterrà al posto di char* nome char nome[4], metterà "e " nei primi due posti di cognome e poi troncherà "Alighieri".

    quando vuoi leggere 20 byte da un file binario, devi passargli precisamente una struttura di 20 byte.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.