将uint8_t转换为字符串[C]

4
我会尝试将一个uint8_t数组[uint8_t lets_try[16]]翻译成一个由16*8+1[空字符]元素组成的字符串。例如:
lets_try[0] = 10101010  
lets_try[1] = 01010101  

我希望能得到类似以下字符串:

1010101001010101...[\0]

这里有问题:1)有没有快速的方法来执行此操作?

我试着自己做;我的想法是从将单个uint8_t变量转换为字符串开始,并使用循环获得完整数组[我还没有完成这最后一部分]。最后我写了这段代码:

int main()
{
    uint8_t example = 0x14;
    uint8_t *pointer;
    char *final_string;

    pointer = &example;

    final_string = convert(pointer);
    puts(final_string);

    return(0);
}


char *convert (uint8_t *a)
{
    int buffer1[9];
    char buffer2[9];
    int i;
    char *buffer_pointer;

    buffer1[8]='\0';

    for(i=0; i<=7; i++)
        buffer1[7-i]=( ((*a)>>i)&(0x01) );

    for(i=0; i<=7; i++)
        buffer2[i] = buffer1[i] + '0';

    buffer2[8] = '\0';

    puts(buffer2);

    buffer_pointer = buffer2;

    return buffer_pointer;
}

以下是需要翻译的内容:

2) 我不确定我完全理解我在线上找到的这个表达式中的奥妙: buffer2[i] = buffer1[i] + '0'; 能否有人解释一下为什么没有+' 0',下面的puts(buffer2) 不会正确工作?是因为空字符使puts()知道它正在打印一个真正的字符串吗?

3) 在上面的代码中,puts(buffer2) 给出了正确的输出,而主函数中的puts却没有任何输出;我对代码进行了反复查找,但找不出问题在哪里。

4) 在我的解决方案中,我设法将uint8_t转换为字符串,通过int数组: uint8_t-> int array-> string; 是否有一种方法可以缩短这个过程,直接从uint8_t传递到字符串,或者改进它?[在论坛中我只找到了C ++的解决方案]它可以工作,但我觉得有点重,不太优雅。

感谢大家的支持。


函数convert调用了未定义的行为,因为它返回一个本地数组。你应该使用malloc - mch
我不清楚你不理解的是什么...第一个循环逐位移出字节,但这会用0或1填充buffer1。添加'0'(即数字48——字符0的ASCII值)将它们转换为文本。在末尾添加'\0'(整数0)以终止字符串,这样puts()就知道在哪里停止了。 - Lee Daniel Crocker
1
“01010101”不是八进制数,而“10101010”是十进制数吗? - Mike Samuel
2个回答

5

1.) 去除 int 数组的速度略快一些。

2.) 添加 '0' 会将整数值 01 更改为它们的 ascii 值 '0''1'

3.) 返回局部变量的地址是未定义行为。您必须在堆上分配内存。

4.) 是的,只需将其删除并在一次操作中执行整个操作即可。

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

typedef unsigned char uint8_t;

char *convert(uint8_t *a)
{
  char* buffer2;
  int i;

  buffer2 = malloc(9);
  if (!buffer2)
    return NULL;

  buffer2[8] = 0;
  for (i = 0; i <= 7; i++)
    buffer2[7 - i] = (((*a) >> i) & (0x01)) + '0';

  puts(buffer2);

  return buffer2;
}


int main()
{
  uint8_t example = 0x14;
  char *final_string;

  final_string = convert(&example);
  if (final_string)
  {
    puts(final_string);

    free(final_string);
  }
  return 0;
}

1
这是一种方法...
char *uint8tob( uint8_t value ) {
  static uint8_t base = 2;
  static char buffer[8] = {0};

  int i = 8;
  for( ; i ; --i, value /= base ) {
    buffer[i] = "01"[value % base];
  }

  return &buffer[i+1];
}

char *convert_bytes_to_binary_string( uint8_t *bytes, size_t count ) {
  if ( count < 1 ) {
    return NULL;
  }

  size_t buffer_size = 8 * count + 1;
  char *buffer = calloc( 1, buffer_size );
  if ( buffer == NULL ) {
    return NULL;
  }

  char *output = buffer;
  for ( int i = 0 ; i < count ; i++ ) {
    memcpy( output, uint8tob( bytes[i] ), 8 );
    output += 8;
  }

  return buffer;
};

int main(int argc, const char * argv[]) {
  uint8_t bytes[4] = {  0b10000000, 0b11110000, 0b00001111, 0b11110001 };

  char *string = convert_bytes_to_binary_string( bytes, 4 );
  if ( string == NULL ) {
    printf( "Ooops!\n" );
  } else {
    printf( "Result: %s\n", string );
    free( string );
  }

  return 0;
}

我只需要扩展16字节,有很多方法,这也取决于您所说的快速是指什么。嵌入式系统...?您可以制作翻译表使其更加快速...

更新

char *convert_bytes_to_binary_string( uint8_t *bytes, size_t count ) {
  if ( count < 1 ) {
    return NULL;
  }

  const char *table[] = {
    "0000", "0001", "0010", "0011",
    "0100", "0101", "0110", "0111",
    "1000", "1001", "1010", "1011",
    "1100", "1101", "1110", "1111"
  };

  size_t buffer_size = 8 * count + 1;
  char *buffer = malloc( buffer_size );
  if ( buffer == NULL ) {
    return NULL;
  }

  char *output = buffer;
  for ( int i = 0 ; i < count ; i++ ) {
    memcpy( output, table[ bytes[i] >> 4 ], 4 );
    output += 4;
    memcpy( output, table[ bytes[i] & 0x0F ], 4 );
    output += 4;
  }

  *output = 0;

  return buffer;
};

int main(int argc, const char * argv[]) {
  uint8_t bytes[4] = {  0b10000000, 0b11110000, 0b00001111, 0b11110001 };

  char *string = convert_bytes_to_binary_string( bytes, 4 );
  if ( string == NULL ) {
    printf( "Ooops!\n" );
  } else {
    printf( "Result: %s\n", string );
    free( string );
  }

  return 0;
}

@mch:你的代码非常清晰,哇!非常感谢你花时间从我的哲学/解决方案开始改进我的代码;robert:快速意味着没有中间步骤;你的解决方案是专业级别的,我会仔细研究它,因为它似乎非常可扩展,是的,我正在处理嵌入式系统 ;) lee:我的问题是关于添加“0”的含义。我仍然对返回本地变量错误和为什么malloc解决了所有问题有些疑虑,但我正在查看这个有用的链接:https://dev59.com/2Wct5IYBdhLWcg3wD5WU ciao! - Antonino
请看我的更新答案......我对嵌入式系统进行了优化。有转换表,还用malloc替换了calloc,不需要清零内存,所有字节都会被替换,也没有引用本地缓冲区,只有一个malloc... - zrzka
非常感谢@robert,又一段漂亮的代码...祝你有美好的一天! - Antonino

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