PDA

View Full Version : [C] Riconoscimento byte


deggial
18-01-2007, 11:43
Ciao a tutti, ho un problema con C...
Devo prendere un file ed estrarre byte per byte. Il codice che uso è questo:


#include <iostream>

int main()
{
char buf[30];
int elementi, dimensione;
int n;
FILE *fp, *ft;
int i;

elementi=30;
dimensione=1;

fp=fopen ("C:/provetds/prova2", "r");
n=fread (buf, dimensione, elementi, fp);
ft=fopen ("C:/provetds/ris.txt", "w");


for (i=0; i<30; i++) {
fprintf (ft, "%12d \t %12u \t %12X \n", buf[i], buf[i], buf[i]);
}

return 0;
}


Cioè prendo il file e passo char per char i dati dentro un buffer.
Poi li scrivo su un file di testo per controllo.

Vi riporto i risultati, nella prima colonna ci metto i codici hex originali, quindi nella seconda ci sarà il contenuto di buf[] formattato come intero con segno, nella terza ci sarà l'intero senza segno, nella quarta l'esadecimale.



01 1 1 1
F2 -14 4294967282 FFFFFFF2
03 3 3 3
04 4 4 4
11 17 17 11
1A 62 62 3E
31 3 3 3
41 0 0 0
91 80 80 50


Ci sono due problemi:
1- finchè i numeri sono sotto il 128(decimale), legge bene. Quando sono superiori al 128, fa casini. Nel codice hex aggiunge FFFFFF, e nell'unsigned da numeri assurdi (aggiunge penso la parte relativa all'FFFFFF)
2- alla prima occorrenza di A1 nel file originale, sbaglia a leggere tutti i codici da lì in poi.

Chi può dirmi qualcosa?
Per il problema 1 penso sia una mia incompetenza, il 2 invece non me lo so spiegare.

ps: Il prog è stato compilato su due pc diversi con due compilatori diversi (visual c++ e mingw) è si comporta nello stesso modo

andbin
18-01-2007, 11:56
Innanzitutto i char sono con segno, quindi quando passi buf[i] alla printf, viene fatta la conversione ad int e quindi anche l'estensione di segno. Pertanto devi passare buf[i] & 0xFF.
Poi, ovviamente, dovresti fare dei test sull'apertura, sulla lettura, ecc...

Se ti può essere utile, in <questo> (http://www.hwupgrade.it/forum/showthread.php?t=1360463) thread, al fondo, avevo postato il sorgente per fare un "dump" in esadecimale di un file.

deggial
18-01-2007, 12:02
Innanzitutto i char sono con segno, quindi quando passi buf[i] alla printf, viene fatta la conversione ad int e quindi anche l'estensione di segno. Pertanto devi passare buf[i] & 0xFF.
Poi, ovviamente, dovresti fare dei test sull'apertura, sulla lettura, ecc...

L'idea di fare l'& con FF era venuta anche a me, e in effetti funziona... però il programma deve agire ogni giorno su una mole di dati molto elevata (nell'ordine dei 3.000.000 byte) e salvarli in un db, ancora non ho fatto una stima di quanto tempo ci possa mettere, ma meno operazioni gli faccio fare meglio è.
non c'è una soluzione per fargli leggere già nel modo giusto?

ps: per il problema dell'A1 puoi ipotizzare qualcosa? ho provato con vari spezzoni di file, e appena trova l'A1 si ripresenta il problema...

pps: grazie per l'esempio di dump, ora lo guardo

andbin
18-01-2007, 12:16
non c'è una soluzione per fargli leggere già nel modo giusto?Dichiara il buffer come unsigned char

ps: per il problema dell'A1 puoi ipotizzare qualcosa? ho provato con vari spezzoni di file, e appena trova l'A1 si ripresenta il problema...1Ah vorrai dire .... è il carattere di end-of-file e viene trattato come tale se il file è aperto non in modalità binaria. Devi mettere (come nell'esempio che ho fatto in quel thread), "rb" come modo di apertura. Poi dipende dalla implementazione della libreria di I/O. Ad esempio sui sistemi Linux il flag 'b' è accettato ma del tutto ignorato. Su altri SO può essere necessario per garantire una lettura "binaria".

deggial
18-01-2007, 12:24
Dichiara il buffer come unsigned char

1Ah vorrai dire .... è il carattere di end-of-file e viene trattato come tale se il file è aperto non in modalità binaria. Devi mettere (come nell'esempio che ho fatto in quel thread), "rb" come modo di apertura. Poi dipende dalla implementazione della libreria di I/O. Ad esempio sui sistemi Linux il flag 'b' è accettato ma del tutto ignorato. Su altri SO può essere necessario per garantire una lettura "binaria".

grazie di tutto... come immaginavo sono abbastanza ignorante in materia...