Home > Enterprise >  How to extract values from a string in hexadecimal in a C program?
How to extract values from a string in hexadecimal in a C program?

Time:10-06

I have a hexadecimal string like:

char str[] = "40004A0060007A0034006600";

I want to extract individual values from it like 0x40, 0x00, 0x4A, 0x00 etc.

How to do it?

CodePudding user response:

  • Copy the 2 bytes of interest into a temporary 3 byte array.
  • Null terminate the 3 byte array to turn it into a string.
  • Call strtoul on this array from stdlib.h.

Alternatively you could manually decode it, since it's a trivial thing to do. Mask out nibbles, subtract some ASCII values or do a lookup table check, then multiply the ms nibble by 16.

CodePudding user response:

NOTE: This answer applies to revision 3 of the question. Meanwhile, the question has been modified, thereby invalidating option #1 of my answer. As pointed out in the comments section of the question, this was not OP's fault, though.

You have two options:

  1. Convert the string to an integer type, for example using the function strtoul or strtoull, and then use bit-shifting (>> operator) and bit-masking (& operator) to obtain the desired values. However, due to limitations in the range of values that the data types long and long long can represent, this option is only guaranteed to work with up to 8 hexadecimal digits with strtoul and 16 digits with strtoull. EDIT: Meanwhile, the question has been modified in such a way that the string is longer than 16 digits, so this solution is no longer viable.

  2. Obtain the desired values by looking them up directly in the string. For example, if you are looking for the 3rd group of hexadecimal digits, then you will find them using str[4] and str[5]. This will give you two character values. If you want to convert these two hexadecimal characters to the number that they represent, then you can create a string from these two values and then use strtoul on that string.

CodePudding user response:

Since you seem to be a beginner, I broke the task up into its constituent parts. This is a very simple hex dump facility where each step your code needs to take is its own routine. It is a quick and dirty and rather imperfect implementation, but understanding how to improve it will help you learn and write your own.

#include <ctype.h>
#include <stdint.h>
#include <stdio.h>

int
nibble(uint8_t ch) {
    if ((ch >= '0') && (ch <= '9')) {
        return ch - '0';
    }

    if ((ch >= 'A') && (ch <= 'F')) {
        return 10   (ch - 'A');
    }

    if ((ch >= 'a') && (ch <= 'f')) {
        return 10   (ch - 'a');
    }

    /* should never get here if isxdigit was called first */
    return -1;
}

int
next_byte(const char *in)
{

    uint8_t hi = 16 * nibble(*in);
    uint8_t lo = nibble(*(in   1));

    return hi   lo;
}

int points_to_byte(const char *in) {
    return ((*in) && isxdigit(*in))
        && (*(in   1)) && isxdigit(*(in   1));
}

void
dump(const char *in) {
    /* Decide what to do with input that is not a string of hex bytes */
    for (int i = 0; points_to_byte(in   i); i  = 2) {
        printf("%d\n", next_byte(in   i));
    }
}

int
main(int argc, char *argv[]) {
    if (argc < 2) {
        puts("Need hex strings as arguments");
    }

    for (int i = 1; i < argc;   i) {
        dump(argv[i]);
    }
}

When compile this into an executable called t and run it with your input, this is the output I get:

$ ./t 400004a005b002000113efb29f73f57589343e70e5244162edf312e303030322e313420200043472d58585858000000000032303139303833585858585858000000505230474C5043343554334C3343
64 
0  
4  
160
...
67 
52 
195
52

want to convert it into a other string like

 char str1[] ="0x40,0x00,0x4A,0x00,0x60";

Since you do not control the input string, you are going to need to malloc the buffer for the output. That and storing the transformed output is left as an exercise.

  •  Tags:  
  • c
  • Related