Question

Here's my problem, I have a byte struct that looks like these:

struct machinecode{
    char byte1[2];
    char byte2[2];
    char byte3[2];
    char byte4[2];
    char byte5[2];
    char byte6[2];
    char byte7[2];
    char byte8[2];
    char byte9[2];
};
struct machinecode WRITEME[500];

now, these collection of 2byte chars or strings are formatted in hex bytes that looks like these for example:

byte1 = "01"

byte2 = "C0"

char bytes are assigned like these:

...
char * returner
...
strncpy(WRITEME[index].byte1, "00", 2);
strncpy(WRITEME[index].byte2, returner, 2);

my printing code looks like these:

while(counter < max){
...
    else if(prog_counter[counter2] == 2){
            fprintf(w, ???, WRITEME[counter].byte1);
            fprintf(w, ???, WRITEME[counter].byte2);
    }
...
}

Now I wanted this to print string as hex bytes, what kind of formatting(???) do I need to use for fprintf? or do I need to convert this hex byte string first to int before fprinting them?

I tried "%x", "%X" but they doesn't work.

EDIT:

I would like to add that I'm making a .com executable file, so I need to print them as hex bytes.

Was it helpful?

Solution

Revised answer

You say "I'm making a .COM executable file so I need to print them as hex bytes". The immediate response is then "Why on earth are you converting the values into a pair of bytes in the first place?" You'll have to convert them back to a single byte and then write that byte using the %c notation. One way, probably not the best way, to do that is:

static const char hexits[] = "0123456789ABCDEF";
static inline int byte_from_hex(const char *hex)
{
    assert(isxdigit(hex[0]) && isxdigit(hex[1]));
    int b1 = strchr(hexits, toupper((unsigned char)hex[0])) - hexits;
    int b2 = strchr(hexits, toupper((unsigned char)hex[1])) - hexits;
    return b1 * 16 + b2;
}

fprintf(w, "%c", byte_from_hex(WRITEME[counter].byte1);

But it would be far simpler not to convert to a string in the first place.

Original answer

Because your data is not null terminated, you need to use a length in the conversion specifications, as specified in the fprintf() manual page:

%.2s

This means print at most 2 characters from the character array.

fprintf(w, "%.2s", WRITEME[counter].byte1);

This assumes you did something like:

WRITEME[counter].byte1[0] = '0';
WRITEME[counter].byte2[1] = '1';

or:

memmove(WRITEME[counter].byte1, "01", sizeof(WRITEME[counter].byte1);

or (as the comments showed you did):

strncpy(WRITEME[counter].byte1, "01", 2);  // or sizeof(WRITEME[counter].byte1)

and that you did not do something like:

sprintf(WRITEME[counter].byte1, "%2X", byte_value);

and that you did not do something like:

strcpy(WRITEME[counter].byte1, "01");

OTHER TIPS

Here's how I fix this.

First I used Jonathan's solution of using sscanf and printf.

Then I encountered a weird bug that puts random "0d" on my file.

The solution was to open and write the file in binary mode.

w = fopen( filename , "wb" );

Hope this helps other users in the future

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top