3

I am newbie to this topic. I am trying to convert integer array to string. Then string to integer array to check if I am getting same input.

gint16 frame[5] = {10, 2, 3, 7, 5};
char *str = malloc(sizeof(char) * (sizeof(frame)+1));
char *strp = str;
size_t j;
for (j= 0; j < sizeof(frame); j++) {
     snprintf(strp, 4, "%02x", frame[j]);   //hexadecimal 
      strp++;
}
// from hexa string to 16 bit integer array
gint16 n_oframe[5];
size_t i_m;
for (i_m = 0; i_m < 5; i_m++) {
     char *d = (char*)malloc(sizeof(gint16));
     strncpy(d,str,2);
     n_oframe[i_m] = atol(d);
     str = str + 2;
     free(d);
}

When I try to print out n_oframe values, I am getting in correct results. Please help me

3
  • 2
    What is sizeof(char) * (sizeof(frame)+1) supposed to give? Especially given the type of frame.. Commented Nov 14, 2016 at 15:22
  • The length of the array (number of elements) is sizeof frame / sizeof frame[0]. Commented Nov 14, 2016 at 15:28
  • free(str); would crash as you have incremented str. Commented Nov 14, 2016 at 15:37

2 Answers 2

1

Use these functions:

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

typedef int16_t gint16;  // define gint16 if not compiling with glib.h

char *gint16_to_string(gint16 *p, int n) {
    char *str = malloc(n * 4 + 1);
    if (str) {
        for (int i = 0; i < n; i++) {
            snprintf(str + i * 4, 5, "%04X", p[i] & 0xFFFF);
        }
    }
    return str;
}

void string_to_gint16(gint16 *p, int n, const char *str) {
    if (str) {
        for (int i = 0; i < n; i++) {
            unsigned int x = 0;
            sscanf(str + i * 4, "%4x", &x);
            p[i] = (gint16)x;
        }
    }
}

int main(void) {
    gint16 frame[5] = { 10, 2, 3, 7, 5 };

    // encoding in hexadecimal
    char *str = gint16_to_string(frame, 5);
    printf("encoded string: %s\n", str);

    // from hexa string to 16 bit integer array
    gint16 n_oframe[5];
    string_to_gint16(n_oframe, 5, str);

    printf("n_oframe: ");
    for (int i = 0; i < 5; i++) {
        printf("%d, ", n_oframe[i]);
    }
    printf("\n");

    free(str);
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

If gint16 is a signed type on a 32-bit int system, gint16 frame[5] = { -256 }; will print FFFF - not likely intended. OTOH, OP's post lacks clarity on this consideration. Suggest snprintf(str + i * 4, 5, "%04X", p[i] & 0xFFFFu);
@chux: very good point, I though of using %04hX but short could be larger than 16 bits, answer updated.
1

The commenters found most of it, so to put it all together

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

// ALL CHECKS OMMITTED!

int main()
{
  int16_t frame[5] = { 10, 2, 3, 7, 5 };
  // hexadecimal string = 2 characters plus NUL
  // sizeof(char) == 1, if compiler is standard compliant
  char *str = malloc(3 * (sizeof(frame)/sizeof(frame[0]) +1));
  char *strp = str;
  size_t j;
  for (j = 0; j < sizeof(frame)/sizeof(frame[0]); j++) {
    // again: hexadecimal string = 2 characters plus NUL
    snprintf(strp, 3, "%02x", frame[j]);        //hexadecimal 
    strp += 2;
  }
  // we need a pointer to the start of the string to free it later
  strp = str;
  // let's see if we gott all of them
  printf("str = %s\n",str);
  // from hexa string to 16 bit integer array
  int16_t n_oframe[5];
  size_t i_m;
  // and again: hexadecimal string = 2 characters plus NUL
  // a simple char d[3]; would have been more than suffcient
  // for the task, but if stack is precious...
  char *d = (char *) malloc(3);
  for (i_m = 0; i_m < 5; i_m++) {
    // it's always the same, just do it once at the beginning
    //char *d = (char *) malloc(3);
    strncpy(d, str, 2);
    // atol() is for base 10 input only, use strtol() instead
    n_oframe[i_m] = (int16_t)strtol(d,NULL,16);
    str = str + 2;
    //free(d);
  }
  for (j = 0; j < 5; j++) {
     printf("%d ", n_oframe[j]);
  }
  putchar('\n');

  free(d);
  free(strp);
  exit(EXIT_SUCCESS);
}

I changed gint16 to int16_t because I do not know what that is supposed to be. You can most likely replace it with gint16 without problems.

2 Comments

Better to insure a limited output with snprintf(strp, 3, "%02x", 0xFFu & frame[j]);. An int16_t could have values like 4096 or -1 which will exceed the allocated buffer.
@chux snprintf handles it automatically. int16_t frame[5] = { 10, 4096, -1, 7, 5 } will result in teh string 0a10ff0705 (10, 16, 255, 7, 5). snprintf returns the number of characters it would have printed if enough space would have been available. You need to check that, but as written on top of the code: all checks ommitted! (including spell checking).

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.