0

I have my data field as follows DATA = 0x02 0x01 0x02 0x03 0x04 0x05 0x06 0x07 Now I want to concatenate this data as follows DATA = 0x01020304050607. How can I do it using C program. I found a program in C for concatenation of data in an array and the program is as follows:

#include<stdio.h>

int main(void)
{
    int num[3]={1, 2, 3}, n1, n2, new_num;
    n1 = num[0] * 100;
    n2 = num[1] * 10;
    new_num = n1 + n2 + num[2];
    printf("%d \n", new_num);
    return 0;
}

For the hexadecimal data in the array how can I manipulate the above program to concatenate the hexadecimal data?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user8540390
  • 143
  • 1
  • 10

3 Answers3

1

You need a 64 bit variable num as result, instead of 10 as factor you need 16, and instead of 100 as factor, you need 256.

But if your data is provided as an array of bytes, then you can simply insert complete bytes, i.e. repeatedly shifting by 8 bits (meaning a factor of 256):

int main(void)
{
    uint8_t data[8] = { 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
    unsigned long long num = 0;
    for (int i=0; i<8; i++) {
        num <<=8;  // shift by a complete byte, equal to num *= 256
        num |= data[i];  // write the respective byte
    }
    printf("num is %016llx\n",num);
    return 0;
}

Output:

num is 0201020304050607
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • 1
    The conversion format `%llx` might not be appropriate for `uint64_t`. You should cast the operand as `unsigned long long`, or simply use this type for `num` as it is specified as having at least 64 value bits. – chqrlie Jun 25 '18 at 06:41
1

Lest say you have input like

int DATA[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

If you want output like 0x0001020304050607, to store this resultant output you need one variable of unsigned long long type. For e.g

int main(void) {
        int DATA[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
        int ele = sizeof(DATA)/sizeof(DATA[0]);
        unsigned long long mask = 0x00;
        for(int row = 0; row < ele; row++) {
                mask = mask << 8;/* every time left shifted by 8(0x01-> 0000 0001) times   */
                mask = DATA[row] | mask; /* put at correct location */
        }
        printf("%016llx\n",mask);
        return 0;
}
Achal
  • 11,821
  • 2
  • 15
  • 37
1

Here's some kind of hack that writes your data directly into an integer, without any bitwise operators:

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

uint64_t numberize(const uint8_t from[8]) {
    uint64_t r = 0;
    uint8_t *p = &r;

    #if '01' == 0x4849 // big endian
        memcpy(p, from, 8);
    #else // little endian
        for (int i=7; i >= 0; --i)
            *p++ = from[i];     
    #endif

    return r;
}

int main() {
    const uint8_t data[8] = { 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

    printf("result is %016llx\n", numberize(data));

    return 0;
}

This does work and outputs this independently of the endianness of your machine:

result is 0201020304050607

The compile-time endianness test was taken from this SO answer.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • 1
    The preprocessor endianness test is unreliable and unspecified per the C Standard. You can use a runtime check that will be optimized out by the compiler, or you can use a simple and readable loop: `int i; uint64_t r = 0; for (i = 0; i < 8; i++) { r = (r << 8) | from[i]; } return r;` – chqrlie Jun 25 '18 at 06:39
  • 1
    The conversion format `%llx` might not be appropriate for `uint64_t`. You should cast the operand as `unsigned long long`. – chqrlie Jun 25 '18 at 06:41