Home > database >  How to convert string of hex to insert into binary file in C
How to convert string of hex to insert into binary file in C

Time:09-28

I need to take in some input that is a string and turn it into its equal hex number and put it in place in a binary file.

        char *fpath = argv[3];
        FILE *f = fopen(fpath, "wb ");
        char buf[1000];
        char *input = "46AB";

        unsigned int value = strtol(input , NULL, 16);
        sprintf(buf, "\\x%x", value);
        fseek(f, 2, SEEK_SET);
        fputs(buf, f);

In the file it produces

5C 78 34 36 61

while i need it look like

46 AB

Is there an elegant way of doing this?

CodePudding user response:

Your sprintf call created the string

\x46ab

and you wrote those six characters to the file without further interpretation, so that's what you saw in the file (hex bytes 5c 78 34 36 61 62).

To avoid byte order issues, and to anticipate the possibility of an arbitrary-length input string, you can do this one byte at a time with code like this:

char *p;
for(p = input; *p != '\0'; p  = 2) {
    unsigned int x;
    if(sscanf(p, "%2x", &x) != 1) break;
    putc(x, f);
}

This uses sscanf to convert the input string to hexadecimal, two characters (two hexadecimal digits, or one byte) at a time.

I also tested it after doing

input = "0102034a4b4c";

This is quick-and-dirty, imperfect code. It will misbehave if input contains an odd number of characters, and it doesn't deal particularly gracefully with non-hexadecimal characters, either.

An improvement is to use the mildly obscure %n format specifier to scanf to discover exactly how many characters it consumed:

for(p = input; *p != '\0'; ) {
    unsigned int x;
    int n;
    if(sscanf(p, "%2x%n", &x, &n) != 1) break;
    putc(x, f);
    p  = n;
}

This should be more robust against malformed input strings, although I have not tested it exhaustively. (I hardly ever use functions in the scanf family, let alone the more obscure format specifiers like %n, but this is one of the few problems I know of where it's attractive, the alternatives being considerably more cumbersome.)

P.S. I got rid of your fseek call, because I wasn't sure what it was there for and it confused my testing. You can put it back in if you need it.

  • Related