Abu Abu - 21 days ago 8
C Question

converting signed integer array to char array

I am trying to convert an signed integer array to character pointer. I wrote a sample programe like below.
Expected output be "10-26357-35"
Please help me.

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

int main(void) {
int16_t frame_i[5] = {10, -26, 35, 7, -35};
size_t i;
char *s = malloc(5*2+1);
for(i = 0; i<5; i++) {
snprintf(s + i * 2, 3, "%hd", frame_i[i]);
}
return 0;
}

Answer

You have to take the sign into account. In other words - you can't just assume all numbers to be 2 chars width.

Try something like:

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

int main(void) {
   int16_t frame_i[5] = {10, -26, 35, 7, -35};
   size_t i;
   char *s = malloc(5*3+1);  // Allocate memory to hold 3 chars for each number

   char *tmp = s;            // Add a tmp pointer to know how far you are

   for(i = 0; i<5; i++) {
    if (frame_i[i] >= 0)     // Check the sign
    {
        snprintf(tmp, 3, "%02hd", frame_i[i]);  // Requires 2 chars
        tmp += 2;
    }
    else
    {
        snprintf(tmp, 4, "%03hd", frame_i[i]);   // Requires 3 chars
        tmp += 3;
    }
   }

   // Print the result
   printf("%s\n", s);

   // Release memory
   free(s);

   return 0;
}

Notice that the solution only works for numbers in the range -99 to 99 and that it will put a 0 in front of number in the range -9 to 9.

A more general (and simpler) solution which handles a wider range and doesn't add 0 in front can be obtained by utilizing that snprintf returns the number of characters printed. Something like:

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

#define MAX_STRING_SIZE 1000

int main(void) {
   int16_t frame_i[5] = {10, -26, 35, 7, -35};
   size_t i;
   int cnt;
   char *s = malloc(MAX_STRING_SIZE);
   char *tmp = s;
   for(i = 0; i<5; i++) {
    tmp += snprintf(tmp, MAX_STRING_SIZE-strlen(s), "%hd", frame_i[i]);
   }
   printf("%s\n", s);
   free(s);
   return 0;
}