Newsgroup: it.comp.lang.c
Titolo: Conversione:Hex->Dec e viceversa, problema.

Ciao a tutti,
     ho realizzato un programmino in C standard che converte un file
qualunque, in un formato Hexadecimale,e viceversa, in uscita ogni "byte"
avra' al seguito un ritorno a capo.(mi serve che sia scritto cosi' per
forza).
Il problema strano e irrisolto e' che fintanto che il file e' un file di
testo, tutto funziona(a parte dei caratteri in piu' alla fine del
file..!!!!!! non so perche')
Se invecegli do' in pasto un file "binario", non ottengo il risultato
voluto. non ottengo cioe' la rappresentazione corretta, e non torna nemmeno
la dimensione.....del file in uscita come ci si aspeterebbe.
Vi allego il programmino completo, funziona ovviamente su Linux e anche su
Windows sperando che qualcuno piu' attento di me trovi il Baco dei Bachi...
:-)
-------------------------------------------------
#include <stdio.h> 
#include <stdlib.h> 
 
 
 
unsigned char hexdec(unsigned char hex_byte[2]){ 
        unsigned char byte_value = 0; 
 
        switch (hex_byte[0]) { 
                case '0' : byte_value =  0<<4;break; 
                case '1' : byte_value =  1<<4;break; 
                case '2' : byte_value =  2<<4;break; 
                case '3' : byte_value =  3<<4;break; 
                case '4' : byte_value =  4<<4;break; 
                case '5' : byte_value =  5<<4;break; 
                case '6' : byte_value =  6<<4;break; 
                case '7' : byte_value =  7<<4;break; 
                case '8' : byte_value =  8<<4;break; 
                case '9' : byte_value =  9<<4;break; 
                case 'A' : byte_value = 10<<4;break; 
                case 'B' : byte_value = 11<<4;break; 
                case 'C' : byte_value = 12<<4;break; 
                case 'D' : byte_value = 13<<4;break; 
                case 'E' : byte_value = 14<<4;break; 
                case 'F' : byte_value = 15<<4;break; 
        } 
 
        switch (hex_byte[1]) { 
                case '0' : byte_value +=  0;break; 
                case '1' : byte_value +=  1;break; 
                case '2' : byte_value +=  2;break; 
                case '3' : byte_value +=  3;break; 
                case '4' : byte_value +=  4;break; 
                case '5' : byte_value +=  5;break; 
                case '6' : byte_value +=  6;break; 
                case '7' : byte_value +=  7;break; 
                case '8' : byte_value +=  8;break; 
                case '9' : byte_value +=  9;break; 
                case 'A' : byte_value += 10;break; 
                case 'B' : byte_value += 11;break; 
                case 'C' : byte_value += 12;break; 
                case 'D' : byte_value += 13;break; 
                case 'E' : byte_value += 14;break; 
                case 'F' : byte_value += 15;break; 
        } 
 
        return byte_value; 
 
 
} 
 
void HexToBin(char *filename){ 
        FILE *srcfile; 
        FILE *dstfile; 
 
        char ch; 
        unsigned char hex_code[2]; 
        unsigned char byte_code; 
 
 
 
        char dstfilename[80]; 
        char ext[5]; 
 
        strcpy(ext,".bin"); 
 
        memset(dstfilename,'\0',80); 
        memcpy(dstfilename,filename,strlen(filename)); 
        memcpy(dstfilename+strlen(filename),ext,strlen(ext)); 
 
        srcfile = fopen(filename,"rb"); 
 
        fprintf(stdout,"Source filename: %s\n", filename); 
        fprintf(stdout,"Dest. filename: %s\n", dstfilename); 
 
        dstfile = fopen(dstfilename,"wb"); 
 
        fprintf(stdout,"Conversione Hex To Byte in corso...\n"); 
 
        while (!feof(srcfile)) { 
                fread(hex_code,2,1,srcfile); 
                byte_code = hexdec(hex_code); 
                fprintf(dstfile,"%c",byte_code); 
        }  
 
        fprintf(stdout,"\nConversione completata...\n"); 
 
        fclose(srcfile); 
        fclose(dstfile); 
} 
 
void BinToHex(char *filename){ 
        FILE *srcfile; 
        FILE *dstfile; 
 
        char byte_code; 
 
        char dstfilename[80]; 
        char ext[5]; 
        char str[3]; 
 
        strcpy(ext,".hex"); 
 
        srcfile = fopen(filename,"rb"); 
 
        memset(dstfilename,'\0',80); 
        memcpy(dstfilename,filename,strlen(filename)); 
        memcpy(dstfilename+strlen(filename),ext,strlen(ext)); 
 
        fprintf(stdout,"Source filename: %s\n", filename); 
        fprintf(stdout,"Dest. filename: %s\n",  dstfilename); 
 
        dstfile = fopen(dstfilename,"wb"); 
 
        fprintf(stdout,"\nConversione Byte To Hex in corso...\n"); 
 
        while (!feof(srcfile)) { 
                fread(&byte_code,1,1,srcfile); 
                fprintf(dstfile,"%02X",(char) byte_code); 
//              fprintf(stdout," %02X-",(char)byte_code); 
        }  
 
        fprintf(stdout,"Conversione completata...\n"); 
 
        fclose(srcfile); 
        fclose(dstfile); 
} 
 
int main(int argc, char *argv[]) { 
        if (argc != 3) { 
                fprintf(stderr,"ERROR: Parameter Unknown or isn't
available\n"); 
                fprintf(stdout,"Usage: %s {-d | -h} filename\n",argv[0]); 
                return; 
        } 
 
        if (!strcmp(argv[1],"-d")) HexToBin(argv[2]); else 
        if (!strcmp(argv[1],"-h")) BinToHex(argv[2]);  
                else 
                        fprintf(stderr,"ERROR: Parameter Unknown!!!\n"); 
 
        system("pause"); 
 
        return 0; 
} 
 

grazie per la risposta,
    allora ho ridotto di molto il codice con i tuoi consigli,
    e ho modificato un po' le funzioni, ora c'e' una sola funzione, e
specificando un parametro (HEX_BIN o BIN_HEX) e' possibile creare una sola
funzione che puo' compiere le due conversioni.
Inizialmente ho verificato la bonta' del codice che ho scritto io, e dopo
aver corretto la fread e strcpy, il codice andava.
Ho sostituito poi il codice che mi hai scritto nei msg precedenti, e
funziona.
ho sistemato poi con dimensione 3 hex_byte, in modo da leggere sempre 3
caratteri, MA utilizzandone due soltanto per la conversione, (cosi' si
salta il '\n' inserito dalle conversioni BIN_HEX).
mi e' poco chiaro il problema che hai posto per i carateri spuri, potresti
essere piu' preciso?
Il problema ora sta tutto nei file binari(non e' presente per i file di
testo) e' la presenza dopo la conversione BIN_HEX, di gruppi di caratteri
FFFFFFF presenti ogni tanto!!!
Non capisco perche'. eppure nel ciclo while per la BIN_HEX ho PROPRIO
specificato cosa scrivere e quanto scrivere. credo valga per tutti i byte
possibili da 0x00 a 0xFF.
Il mio obiettivo e' convertire TUTTI i caratteri di un file (testo o binario
non importa) quindi se sono presenti caratteri spuri nel file originale,
poco importa, l'importante e' che, ovvio, dal file originale e
riconvertendo, BIN_HEX e HEX_BIN si riottenga un file identico, byte a
byte.
ti riposto il codice corretto e revisionato da me:
-----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
unsigned int H[256];
enum {HEX_BIN,BIN_HEX};
inline unsigned int hexdec(unsigned char hex_byte[3]) {
        return (H[hex_byte[0]]<<4) + H[hex_byte[1]];
}
void Conversion(char *srcfilename,int type) {
        FILE *srcfile;
        FILE *dstfile;
        unsigned char hex_code[3];
        unsigned char byte_code;
        char dstfilename[80];
 
        strcpy(dstfilename,srcfilename);
        if (type == HEX_BIN) strcat(dstfilename,".bin");
        if (type == BIN_HEX) strcat(dstfilename,".hex");
 
        fprintf(stdout,"Source filename: %s\n", srcfilename);
        fprintf(stdout,"Dest. filename: %s\n",  dstfilename);
        if ((srcfile = fopen (srcfilename, "rb")) == NULL) fprintf(stdout,"ERROR:
Errore apertura file Sorgente...\n");
        if ((dstfile = fopen (dstfilename, "wb")) == NULL) fprintf(stdout,"ERROR:
Errore apertura file Destinazione...\n");
 
        if (type == HEX_BIN) fprintf(stdout,"\nConversione Hex To Byte in
corso...\n");
        if (type == BIN_HEX) fprintf(stdout,"\nConversione Byte To Hex in
corso...\n");
        if (type == HEX_BIN) 
                while (fread(hex_code,3,1,srcfile)==1)
                        fprintf(dstfile,"%c",byte_code = hexdec(hex_code));
        if (type == BIN_HEX) 
                while (fread(&byte_code,1,1,srcfile)==1) 
                        fprintf(dstfile,"%02X\n",byte_code);
        fprintf(stdout,"\nConversione completata...\n");
        fclose(srcfile);
        fclose(dstfile);
}
int main(int argc, char *argv[]) {
        unsigned int i;
 
        if (argc != 3) {
                fprintf(stderr,"ERROR: Parametro sconosciuto o non disponibile!\n");
                fprintf(stdout,"Syntax: %s {-d | -h} filename\n",argv[0]);
                return -1;
        }
        for (i=0; i<256; i++) {
                if (i<='9'&& i>='0') {H[i]=i-'0';continue;}
                if (i<='f'&& i>='a') {H[i]=i-'a'+10;continue;}
                if (i<='F'&& i>='A') {H[i]=i-'A'+10;continue;}
                H[i]=255; /* valore > 15 */
        }
 
 
        if (!strcmp(argv[1],"-d")) Conversion(argv[2],HEX_BIN); 
        else
        if (!strcmp(argv[1],"-h")) Conversion(argv[2],BIN_HEX); 
        else
        fprintf(stderr,"ERROR: Parametro sconosciuto!!!\n");
 
        fprintf(stdout,"Premi un tasto per continuare...\n");
        getchar();
        return 0;
}
-----------------------------------------------------------------
-- 
---
Info SkyStar2 Satellite Card for Linux Device Drivers: 
http://www.assitecforum.com
 (Section: SkyStar2 for Linux)