Search code examples
ccastingembeddediotuint8t

How to convert a uint8_t array to a character array in C?


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 ?


Solution

  • 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
    }