【问题标题】:conversion of uint8_t to a string [C]将 uint8_t 转换为字符串 [C]
【发布时间】:2014-12-12 16:42:50
【问题描述】:

我正在尝试将 uint8_t [uint8_tlets_try[16]] 数组“翻译”为 16*8+1[null character] 元素的字符串。例如:

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) 我不确定我是否完全理解我在网上找到的这个表达式的魔力: 缓冲区2[i] = 缓冲区1[i] + '0';有人可以向我解释为什么没有 +'0' 下面的 puts(buffer2) 不能正常工作吗?是新生字符串末尾的空字符使 puts() 起作用吗? [因为它知道它正在打印一个真正的字符串?]

3) 在上面的代码中 puts(buffer2) 给出了正确的输出,而 main() 中的 puts 没有给出任何结果;一遍又一遍地看代码我疯了,我找不到它有什么问题

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

感谢大家的支持

【问题讨论】:

  • 函数convert 调用未定义的行为,因为它返回一个本地数组。你应该使用malloc
  • 我不清楚你不明白什么......第一个循环一次移出一个字节的位,但是用数字 0 或 1 填充 buffer1。添加 '0 '(即数字 48——字符 0 的 ASCII 值)将它们转换为文本。将 '\0'(整数 0)添加到末尾会终止字符串,因此 puts() 将知道在哪里停止。
  • 01010101 不是八进制数字文字,10101010 不是十进制数字文字吗?

标签: c arrays string pointers uint8t


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这是一种方法......

    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 个字节。有很多方法,这也取决于您对 quick 的含义。嵌入式系统, ...?您可以制作翻译表以使其更快,...

    更新

    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:你的代码太清晰了,哇!非常感谢您花时间从我的理念/解决方案开始改进我的代码;罗伯特:快速意味着没有中间步骤;你的解决方案是专业的,我会仔细研究它,因为它看起来非常可扩展,是的,我正在研究嵌入式系统;)李:我的问题是关于添加“0”的含义。我仍然对返回局部变量错误以及为什么 malloc 解决了这一切有一些疑问,但我正在看看有用的:stackoverflow.com/questions/12380758/… ciao!
    • 查看我的更新答案...我确实针对嵌入式系统进行了优化。有转换表,也用malloc替换了calloc,不需要内存为零,反正所有字节都会被替换,也没有本地缓冲区的引用,只有一个malloc,...
    • 再次非常感谢@robert,又一段漂亮的代码……祝你有美好的一天!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    相关资源
    最近更新 更多