0

I haven't found any solution among the many many threads about this. My exact problem is:

I have an array of integers such as unsigned int arr[2] = {0xFEBD1213, 0x1213FEBD};

I would like to access those integers char by char, meaning that I need to read : 0x13, 0x12, 0xBD, 0xFE, 0xBD, 0xFE, 0x13, 0x12. I tried many, many things and I did not succeeded yet.

Note : I would also like to do the opposite : having a char array with a size such as size %4 == 0, and reading it as an integer array. E.g : unsigned char arr[8] = {0x13, 0x12, 0xBD, 0xFE, 0xBD, 0xFE, 0x13, 0x12} and read 0xFEBD1213, 0x1213FEBD;

Is there any way of doing such a thing?

Minimal reproducible example:

#include <stdio.h>
#include <stdlib.h>
void main(void){
  unsigned int arr[2] = {0xFEBD1213, 0x1213FEBD};
  unsigned char * ptr;
  ptr = *&arr; // I need a variable. Printing it doesn't matter to me. I am aware that there are easy solutions to print the right values there.
  for(int i = 0; i < 2 * 4; i++){
    printf("%x\n", *ptr);
    ptr = (ptr++);
  }
}

(I am aware that there are many cleaner way to code this, but I don't have the control over the type of the given array)

2
  • ptr = (ptr + i); ==> ptr++; Commented Apr 25, 2020 at 17:46
  • "I did not succeeded yet." What is the failure? You missed an important information. Commented Apr 25, 2020 at 18:02

3 Answers 3

2

A simple shift and AND will work:

#include <stdio.h>
#include <limits.h>

int main (void) {

    unsigned int arr[2] = {0xFEBD1213, 0x1213FEBD};

    for (size_t i = 0; i < 2; i++)
        for (size_t j = 0; j< sizeof *arr; j++)
            printf ("0x%hhx\n", arr[i] >> (j * CHAR_BIT) & 0xff);
}

Example Use/Output

$ ./bin/arrbytes
0x13
0x12
0xbd
0xfe
0xbd
0xfe
0x13
0x12

To go from bytes to array just shift the opposite direction and OR.

Sign up to request clarification or add additional context in comments.

4 Comments

That was not exactly what I needed. I needed a pointer variable from which I can iterate trough the array. Still, thanks for you answer. I posted my solution above.
Love it. Very elegant
@jijuji the problem with using a pointer is it does not take endianess into consideration. If you were to simply iterate over the bytes in 0xFEBD1213 on a little endian machine, your ordering would be 13, 12, BD, FE (where LSB is stored first in memory). When you use shifts, the compiler handles the byte-order appropriately. Try with unsigned char *p = (unsigned char *)arr; and then iterate with for (; p != (unsigned char*)&arr[0] + sizeof arr; p++) -- your byte order is reversed on LE.
@DavidC.Rankin That is exactly what I need, for it to keep the endianess.
0

You can use some kind of a parser:

void AccessAsCharArr(void *arr, size_t size);

int main()
{
    unsigned int arr[] = {0xFEBD1213, 0x1213FEBD, 0xFF000366};
    AccessAsCharArr(arr, sizeof(arr));
    return 0;
}

void AccessAsCharArr(void *arr, size_t size)
{
    unsigned char *ptr = arr;

    for (size_t i = 0; i < size; i++)
    {
        printf("%hhx ", *ptr);
        ptr++;  
    }
}

Comments

-1
#include <stdio.h>
#include <stdlib.h>
void main(void){
  unsigned int arr[2] = {0xFEBD1213, 0x1213FEBD};
  unsigned char * ptr;
  ptr = &arr;
  for(int i = 0; i < 2 * 4; i++){
    printf("%x\n", *ptr);
    ptr = &*(ptr)+1;

  }

  unsigned char arr_c[8] = {0x13, 0x12, 0xBD, 0xFE, 0xBD, 0xFE, 0x13, 0x12};
  unsigned int * ptr_i;
  ptr_i = &arr_c;
  for(int i = 0; i < 2; i++){
      printf("%x\n", *ptr_i);
      ptr_i = &*(ptr_i)+1;
  }
}

2 Comments

Don't post the code without an explanation where the error was.
ptr = &*(ptr)+1; is awful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.