在C语言中将字符串转换为整数数组

3

我对这个话题是新手。我正在尝试将整数数组转换为字符串,然后将字符串转换为整数数组以检查是否得到相同的输入。

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);
}

当我尝试打印n_oframe的值时,结果不正确。请帮助我。

2
sizeof(char) * (sizeof(frame)+1) 应该返回什么?特别是考虑到 frame 的类型。 - Eugene Sh.
数组的长度(元素数量)为 sizeof frame / sizeof frame[0] - Weather Vane
free(str); 会导致崩溃,因为您已经增加了 str 的值。 - Karthick
2个回答

1
请使用这些函数:

#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;
}

如果 gint16 是一个有符号类型在一个32位的 int 系统上,gint16 frame[5] = { -256 }; 将会打印出 FFFF - 这很可能不是预期的。另一方面,OP 的帖子在这个问题上缺乏清晰度。建议使用 snprintf(str + i * 4, 5, "%04X", p[i] & 0xFFFFu); - chux - Reinstate Monica
1
@chux: 非常好的观点,我本来想使用%04hX,但是short可能大于16位,已更新答案。 - chqrlie

1

评论者已经找到了大部分,所以将它们整合在一起

#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);
}

我将更改为,因为我不知道它应该是什么。你很可能可以无问题地将其替换为。

最好使用snprintf(strp,3,“%02x”,0xFFu&frame [j])来保证有限的输出。 int16_t可能具有像4096或-1这样的值,超出了分配的缓冲区。 - chux - Reinstate Monica
@chux snprintf 会自动处理。int16_t frame [5] = {10,4096,-1,7,5} 将导致字符串 0a10ff0705(10、16、255、7、5)。snprintf 返回它 本应 打印的字符数,如果有足够的空间。您需要检查它,但如代码顶部所述:所有检查都被省略了!(包括拼写检查)。 - deamentiaemundi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接