Da Char a Void Pointer - File

di il
15 risposte

Da Char a Void Pointer - File

Buonasera a tutti,
ho un problema con la conversione da char a void pointer, ma in particolare con l'utilizzo del puntatore successivamente alla conversione. Per spiegare meglio il mio problema ho scritto un piccolo codice esemplificativo, che è il seguente:
#include <stdio.h>
#include <stdlib.h>

void stampaVoidPointer(void * p);
void * leggiCHARdaFile(FILE *f);

int main()
{
    FILE *f;
    void * p;

    f=fopen("CHAR.txt","r");
    p=leggiCHARdaFile(f);
    printf("Main: Char from void pointer: %c\n",*((char*)p)); //STELLA
    stampaVoidPointer(p);
    fclose(f);
    system("PAUSE");
    return 0;
}

void stampaVoidPointer(void * p){
    printf("In funzione: Char from void pointer: %c\n",*((char*)p));
    }

void * leggiCHARdaFile(FILE *f){
    char a= fgetc(f);
    void * v=&a;
    ungetc(a,f);
    return v;
    }
Il mio codice preleva tramite la funzione leggiCHARdaFile un carattere contenuto in un file, e lo trasforma in un putatore a void che verrà utilizzato successivamente nel main in due successive stampe. Il problema che si verifica è il seguente.. la stampa avviene una sola volta. Mi spiego meglio.. Eseguito così si visualizzerà il contenuto di p soltanto con la printf al rigo 'STELLA', mentre invece se commento il rigo 'STELLA' la stampa si verificherà all'interno della funzione stampaVoidPointer. Come mai succede questo? E' forse sbagliata la conversione? O cos'altro mi impedisce di utilizzare il puntatore più di una volta?
Chiaramente questo codice l'ho scritto apposta per evidenziare il problema che mi è sorto in un progetto ben più complesso in cui mi occorre fare queste operazioni e conversioni, che possono sembrare insignificanti in questo contesto.

Grazie a chi mi risponderà!

15 Risposte

  • Re: Da Char a Void Pointer - File

    Non devi restituire puntatori a variabili locali perché queste aree sono distrutte alla fine delle funzioni, come saprai.
  • Re: Da Char a Void Pointer - File

    E' allocata dinamicamente, all' uscita della funzione verrà distrutto v ma l'indirizzo a cui puntava è stato restituito a void * p presente nel main. Io ho notato che se inverti le due stampe ,il tutto avviene correttamente. Perciò mi viene da pensare che il cast esplicito nella printf modifichi "qualcosa" in p prima di esser passato alla funzione di stampa
  • Re: Da Char a Void Pointer - File

    In effetti quello che noto è che posso richiamare mille volte la funzione stampa e visualizzarne sempre il risultato, ma è la riga stella che mi fa perdere l'informazione. Credevo appunto che restituendo l'indirizzo a void * p nel main non perdessi l'informazione di v. Sbaglio?! Ho fatto molti tentativi ma in nessun modo riesco a risolvere il problema. Putroppo per me è necessario che la fgetc sia fatta all'interno di una funzione che restituisca il puntatore a void, in quando il file in questo caso contiene un CHAR, ma potrebbe contenere altri tipi di dati, e io scrivo una funzione leggiDaFile per ogni tipo di dato diverso nelle rispettive librerie.
  • Re: Da Char a Void Pointer - File

    Allora semplicemente crea nel main una variabile puntatore di tipo (quello che contiene p,in questo caso un char *), lo allochi anche per un singolo carattere altrimenti crasherebbe; poi dopo aver assegnato a p il valore di ritorno della funzione leggi , successivamente copi il contenuto di p (castato) nell 'altro puntatore. Insomma ci stai facendo una copia. Esempio:
    
    int main()
    {
    
        FILE *fp;
        void * p;
        char* copy = malloc(sizeof(char));
    
        fp=fopen("CHAR.txt","r");
        if(fp!=NULL)
        {
        	p=leggiCHARdaFile(fp);
        	*copy = *(char *) p;
        	printf(" Main: Char from void pointer: %c\n  ",*copy);   //STELLA
        	stampaVoidPointer(p);
        }
        else
        	perror("errore nell apertura del file! controlla path\n");
        fclose(fp);
        system("PAUSE");
        return 0;
      }
    
    
    
  • Re: Da Char a Void Pointer - File

    Scherzo, andava perchè la riga printf nel main era al di sotto della chiamata alla funzione di stampa
  • Re: Da Char a Void Pointer - File

    beginner32 ha scritto:


    Scherzo, andava perchè la riga printf nel main era al di sotto della chiamata alla funzione di stampa
    Infatti non funziona ugualmente......
  • Re: Da Char a Void Pointer - File

    Non mi sono spiegato ...

    Queste righe
    
        char a= fgetc(f);
        void * v=&a;
    ..
        return v;
    
    sono sbagliate perché l'area puntata da v non è "affidabile". Non è questione di una riga o di un'altra e non esiste soluzione e non devi fare nessun tentativo. E' una caratteristica del linguaggio e di come funziona l'allocazione della memoria per le variabili locali. In pratica, studiando il C ti rendi conto che questo codice non ha senso.
  • Re: Da Char a Void Pointer - File

    beginner32 ha scritto:


    E' allocata dinamicamente, all' uscita della funzione verrà distrutto v ma l'indirizzo a cui puntava è stato restituito a void * p
    Non ci siamo assolutamente. In primo luogo non vi è alcuna allocazione dinamica. Secondariamente, il puntatore v assume l'indirizzo di char a, una variabile automatica che viene pertanto creata sullo stack frame, il cui contenuto viene irrimediabilmente perduto e sovrascritto all'uscita della funzione, pertanto si tratta comunque di un indirizzo assolutamente inutilizzabile al di fuori della funzione stessa.

    In casi del genere si usano buffer statici condivisi a livello di libreria, non si restituisce un puntatore ma lo si passa come parametro, oppure si utilizzano union o strutture atte a contenere i vari tipi di dato: allocate a monte e passate per indirizzo alla funzione di lettura.
  • Re: Da Char a Void Pointer - File

    Ho capito.
    Io ho una struttura con campo void * key, e siccome le informazioni che prelevo dal file possono essere anch'esse di tipo differente avevo pensato di fare una funzione del genere, così come ho fatto per ogni cosa, ad esempio il confronto. Cioè ho una libreria per ogni tipo di dato, e tramite puntatori a funzioni uso una funzione di un tipo piuttosto che un'altra.. Ed è quello che pensavo di fare anche per la lettura di caratteri da file, in questo modo che appunto ho capito essere errato. Purtroppo non so come altro fare.
  • Re: Da Char a Void Pointer - File

    La questione non ha a che fare con la struttura, i tipi di dati da restituire o altro ma solo con la visibilità del dato che vuoi restituire.

    Devi semplicemente usare l' allocazione dinamica per memorizzare il dato che ti serve e passare il puntatore a tale struttura dove vuoi.

    Conosci come usare le funzioni malloc, free ?
  • Re: Da Char a Void Pointer - File

    beginner32 ha scritto:


    E' allocata dinamicamente
    Scusa, di cosa parli? Non vedo allocazione dinamica ...
  • Re: Da Char a Void Pointer - File

    E' vero,mi sono sbagliato,chiedo venia. Non avevo fatto assolutamente caso alla variabile char a = fgetc(f); di cui come giustamente detto da M.A.W. 1968 una volta terminata la funzione il contenuto viene distrutto.
  • Re: Da Char a Void Pointer - File

    oregon ha scritto:


    beginner32 ha scritto:


    E' allocata dinamicamente
    Scusa, di cosa parli? Non vedo allocazione dinamica ...
    In questo caso sarebbe stato corretto o sbaglio?
    
      char* a= malloc(sizeof(char));
        *a = fgetc(f);
       
     
  • Re: Da Char a Void Pointer - File

    Si, ma non c'era prima...
Devi accedere o registrarti per scrivere nel forum
15 risposte