Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2006
    Messaggi
    64

    [C] problema lettura da file

    ciao a tutti,

    sto scrivendo un programma che scrive e legge dati compressi su file.. e ho un problema..
    praticamente funziona cosi: prendo un file in input d caratteri e li scrivo con fprintf()compressi (cn RLE, cioe carattere-numero di ripetizioni del carattere) in formato:
    - short int per il carattere
    - unsigned short int per il numero di occorrenze
    il tutto su un altro file che poi devo leggere per decomprimerlo e riscriverlo in modo che ritorni uguale all'originale..

    il file compresso riesco a scriverlo senza problemi ma quando vado a leggerlo con fscanf per decomprimerlo debuggando noto dei problemi..

    il file compresso lo scrivo cosi:

    short int BUFFER[BUF_SIZE];

    ...

    for(j = 0; j < BUF_SIZE; j++)
    fprintf(fp, "%hd", BUFFER[j]);

    mentre in fase di lettura uso:

    short int carattere;
    unsigned short int count;

    ...

    fscanf(fp, "%hd", &carattere);

    per i caratteri e

    fscanf(fp, "%hu", &count);

    per le rispettive occorrenze.

    Facendo debug ho scoperto che i caratteri vengono letti bene (cioe legge il valore intero ASCII corretto) mentre per le occorrenze la scanf memorizza nella variabile count il valore 65535 per valori da leggere molto grandi cioe superiori a 30 000..
    il problema secondo voi sta nella formattazione della fscanf? cioe in quel %hu? come posso risolverlo?
    oppure sapreste propormi soluzioni alternative per risolvere il problema?

    scusate il casino..
    grazie
    Ciao!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    65535 è il valore massimo per uno short int. Usa un int per risolvere il problema.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2006
    Messaggi
    64
    ho riscritto tutte le variabili come int pero adesso il valore memorizzato all'interno della variabile carattere è 2147483647 e dentro count 0 per cui c e un errore nella scanf..

    hai qualche idea?

  4. #4
    Utente di HTML.it L'avatar di 810106
    Registrato dal
    Jun 2008
    Messaggi
    67
    Perchè fprintf e fscanf non puoi scrivere in binario!?
    codice:
    ...
    /* scrittura */
      for(j = 0; j < BUF_SIZE; j++)
        fwrite(BUFFER[j], sizeof(short int), 1, fp);
    ...
     /* lettura */
      fread(&carattere, sizeof(short int), 1, fp);
    Piu veloce e piu pratico.

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    fscanf si aspetta un input formattato, per quello si incasina.
    Avresti dovuto scrivere:
    codice:
    for(j = 0; j < BUF_SIZE; j++)
    fprintf(fp, "%hd\n", BUFFER[j]);
    per leggere correttamente con la fscanf.

    L'accoppiata fwrite - fread (come indicato sopra) risolve il problema.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jun 2006
    Messaggi
    64
    ok, grazie...
    formattando la scrittura con quel \n risolvo il problema di lettura..

    volevo chiedere un'ultima cosa..

    se io scrivo un file cn fwrite un dato alla volta posso leggere solo uno alla volta oppure è indifferente? in altre parole il 3° parametro deve essere uguale sia per la fread che per la fwrite oppure no?

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2006
    Messaggi
    64
    Originariamente inviato da quagmire
    ok, grazie...
    formattando la scrittura con quel \n risolvo il problema di lettura..

    volevo chiedere un'ultima cosa..

    se io scrivo un file cn fwrite un dato alla volta posso leggere solo uno alla volta oppure è indifferente? in altre parole il 3° parametro deve essere uguale sia per la fread che per la fwrite oppure no?
    ho notato un altro problema..

    la fscanf non mi rileva la EOF, praticamente quando raggiunge a fine del file non trova -1 ma continua a leggermi l'ultimo carattere..

    cosa puo essere?

    grazie
    ciao

  8. #8
    Utente di HTML.it L'avatar di 810106
    Registrato dal
    Jun 2008
    Messaggi
    67
    fscanf non torna -1, torna il numero di oggetti letti con successo, 0 indica che non ha letto niente del
    formato richiesto. Guarda sul sito www.gnu.org c'è la documentazione della libreria C.

    Riguardo a fread e fwrite:
    prototipo: fread(void *buf, unsigned int OBJECT-SIZE, unsigned int N-OBJECTS, FILE *stream);

    quindi il terzultimo parametro indica la dimensione dell'oggetto che devi leggere, il penultimo quanti di questi
    oggetti vuoi leggere.

    Nel tuo caso era 1 per la dimensione (char ha dimensione 1 byte) e 1 per il numero di caratteri.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2006
    Messaggi
    64
    scusa forse non mi sono spiegato bene...
    quello che volevo chiederti era:

    se io scrivo un file con fwrite un dato (qualsiasi) alla volta (e quindi con N-OBJECTS = 1) allora questo stesso file che vado successivamente a leggere con fread deve per forza essere letto 1 dato alla volta (quindi sempre con N-OBJECTS = 1) ? Ovvero l'accoppiata fread e fwrite funziona solo se i dati sono scritti e poi letti a blocchi uguali ?

    se io per dire scrivessi un file a blocchi di 100 dati con fwrite:

    fwrite(BUFFER, sizeof(short int), 100, fp);

    potrei leggere questi 100 dati uno alla volta? per esempio cosi:

    while(){
    ..
    fread(&dato, sizeof(short int), 1, fp);
    ..
    }

    forse è una domanda stupida però volevo chiarire il dubbio..
    grazie

  10. #10
    Utente di HTML.it L'avatar di 810106
    Registrato dal
    Jun 2008
    Messaggi
    67

    :)

    Tranky, credo che il forum sia apposta per chiarire... anche se poi si postano sopprattutto soluzioni ai compiti scolastici...

    tornando al discorso f-read/write:
    Prima cosa ho dimenticato di dirti che se vuoi utilizzare veramente la modalità binaria devi indicarlo quando apri il file aggiungendo il carattere 'b' nelle opzioni di fopen:
    codice:
      in = fopen(PATH, "rb");
      out = fopen(PATH, "wb");
    Riguardo alla modalità di lettura o scrittura... certo se scrivi in binario puoi leggere in binario
    ad esempio supponi di aver scritto su un file un centinaio di strutture con istruzioni come:
    codice:
    fwrite(pointer_to_my_type_object, sizeof(mytype), 1, 1);
    Nell'apertura puoi fare:
    codice:
    mytype *vec;
    struct stat st;
    ...
    binary_input_sream = fopen(PATH, "rb");
    ...
    stat(&st, "FILENAME");
    vec = (mytype*)malloc(st.st_size); /* st.st_size indica la dimensione del file */
    ...
    fread(vec, st.st_size, 1, binary_imput_stream); /* legge un blocco grande quanto il file 1 sola volta */
    ...
    Cosi in un colpo solo hai letto tutto il file in memoria e hai un vettore riempito. Forte eh?

    PS: Ricorda che se le struttura ha dei puntatori come membri questo non lo puoi fare perchè un puntatore
    contiene un indirizzo quindi fwrite scrive quell'indirizzo nel file ma poi quando lo rileggi dentro
    alla struttura quell'indirizzo non è piu valido.

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.