-2

I have a uint8_t array which I want to be able to convert to a char array. i.e. uint_8 myInput [4] = {0, 233, 3, 1};

Which in bits it corresponds to: 00000000 00000011 11101001 00000001

And I would like to have an array of characters: char myChar [10] ={2,5,6,2,5,7}; which is the equivalent number.

I was able to create a solution: MySolution:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>     /* strtol */
#include <stdint.h>
#include <string.h>

int my_uint8_t_to_char (uint8_t givenData[]);


int main ()
    {
    
      uint8_t testArray[4];
      uint32_t monitor_counter;
      char sendBuffer[10];
      monitor_counter = 256257;
    
    // Here we create our array of uint8_t
      memcpy (testArray, &monitor_counter, sizeof (monitor_counter));
    
    // We flip the order of the bits
      for (int i = 0; i < 4 / 2; i++)
        {
          int temp = testArray[i];
          testArray[i] = testArray[4 - 1 - i];
          testArray[4 - 1 - i] = temp;
        }
    
    //Call the function that converts the uint8_t to an integer value
    int beforeSend = my_uint8_t_to_char(testArray);
    printf ("\nHere it is: %d",beforeSend);
   
    
    sprintf(sendBuffer, "%d", beforeSend);
    // for ( int i=0; i< 10;i++)
    printf("\nConverted character: %s",sendBuffer);
      
      
    
      return 0;
    }
    

int my_uint8_t_to_char (uint8_t givenData[])
    {
    
      char biggerArrayToSaveOctades[32];
      int n, c, k, i, w;
      unsigned int arr1[8];
      int arrTemp[8];
      long long bigBinaryString;
    
    
    
      int j;
      int index;
      const int length_A = 8;
      
      char astr[length_A*10];
      char astr2[length_A*10];
      char astr3[length_A*10];
      char astr4[length_A*10];
      printf("\nSIZE: %d",sizeof(astr4));
    
      // In every loop we get one of the 4 integers from the uint8_t array and convert it to binary character 
      for (i = 0; i < 4; i++)
        {

          n = givenData[i];
    
          for (c = 7; c >= 0; c--)
        {
          k = n >> c;
    
          if (k & 1)
            {
              arr1[c] = 1;
            }
          else
            {
              arr1[c] = 0;
            }
        }
    
    
          /*Flip the bits order */
          for (int w = 0; w < 8 / 2; w++)
        {
          int temp = arr1[w];
          arr1[w] = arr1[8 - 1 - w];
          arr1[8 - 1 - w] = temp;
        }

    
    // in each case we append into the biggerArrayToSaveOctades the bitstrings
          switch (i)
        {
    
        case 0:
    
          j = 0;
          index = 0;
    
          for (j = 0; j < length_A; j++)
            {
              index += sprintf (&astr[index], "%d", arr1[j]);
            }
    
          for (w = 0; w < 8; w++)
            biggerArrayToSaveOctades[w] = astr[w];
    
          break;
    
        case 1:
          j = 0;
          index = 0;
    
          for (j = 0; j < length_A; j++)
            {
              index += sprintf (&astr2[index], "%d", arr1[j]);
            }
    
          j = 0;
          for (w = 8; w < 16; w++)
            {
              biggerArrayToSaveOctades[w] = astr2[j];
              j++;
            }
    
          break;
    
        case 2:
          j = 0;
          index = 0;
    
          for (j = 0; j < length_A; j++)
            {
              index += sprintf (&astr3[index], "%d", arr1[j]);
            }
    
          j = 0;
          for (w = 16; w < 24; w++)
            {
              biggerArrayToSaveOctades[w] = astr3[j];
              j++;
            }
    
          break;
    
        case 3:
          j = 0;
          index = 0;
    
          for (j = 0; j < length_A; j++)
            {
              index += sprintf (&astr4[index], "%d", arr1[j]);
            }
    
          j = 0;
          for (w = 24; w < 32; w++)
            {
              biggerArrayToSaveOctades[w] = astr4[j];
              j++;
            }
          break;
        }
    
    
        }
     //Convert the bitstring to integer
      int result = (int) strtol (biggerArrayToSaveOctades, NULL, 2);
    
      return result;
    }

but unfortunately I have some issues with the creation of the char astr[length_A*10]; with the ISO since I am using an IoT device and also I believe that my solution it's pretty complicated and not efficient.

Is there any way of doing that ?

1 Answers1

3

The bytes represent one of the following:

  • 32-bit unsigned integer
  • 32-bit 2's complement signed integer
  • 32-bit 1s' complement signed integer (Extremely unlikely)

A very odd byte order is being used:

  • The first is the most significant
  • The third is the next most significant
  • The second is the next most significant
  • The fourth is the least significant

This is neither big-endian nor little-endian byte order.

First convert the bytes into the appropriate number, then convert the resulting number into its decimal text representation (e.g. using sprintf/snprintf).


32-bit unsigned integer

Convert to number:

#include <stdint.h>

uint32_t num = 
   ( (uint32_t)(myInput[0]) << 24 ) |
   ( (uint32_t)(myInput[2]) << 16 ) |
   ( (uint32_t)(myInput[1]) <<  8 ) |
   ( (uint32_t)(myInput[3]) <<  0 );

For your input, this would be equivalent to

uint32_t num = 256257;

Convert to its decimal representation:

#include <inttypes.h>
#include <stdio.h>

char decimal[11];  // Up to 10 digits plus final NUL.
sprintf(decimal, "%" PRIu32, num);

For your input, this would be equivalent to

char decimal[11] = { '2', '5', '6', '2', '5', '7', 0 };

Test:

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

typedef uint8_t uint_8;  // Why not just use uint8_t??

int main(void) {
   uint_8 myInput[4] = {0, 233, 3, 1};

   uint32_t num =
      ( (uint32_t)(myInput[0]) << 24 ) |
      ( (uint32_t)(myInput[2]) << 16 ) |
      ( (uint32_t)(myInput[1]) <<  8 ) |
      ( (uint32_t)(myInput[3]) <<  0 );

   char decimal[11];  // Up to 10 digits plus final NUL.
   sprintf(decimal, "%" PRIu32, num);

   // If all you want to do is print the number,
   // `printf("%" PRIu32, num);` would do the trick.
   printf("%s\n", decimal);  // 256257
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Unfortunately with the number conversion, I end up with `uint32_t num = 17033472;` instead of the expected `uint32_t = 256257`. But since I can get the value I need from one step before as `uint32_t` due to the functionality of my program, I skipped the number conversion and the `sprintf` solution you provided with the `PRIu32` indeed solved my problem the best way possible. Thank you very much @ikegami ! – Xristos Arthur Xenophontos Apr 02 '21 at 14:18
  • 1
    oops, I got the byte order wrong. It's a very weird byte order! It's the first time I've ever seen an order other than little-endian and big-endian. What you have doesn't even have a name! Answer updated. – ikegami Apr 02 '21 at 18:52