【问题标题】:Converting C string to binary representation将 C 字符串转换为二进制表示
【发布时间】:2011-04-14 17:05:58
【问题描述】:

在 ANSI C 中,我们如何将字符串转换为二进制字节数组? 所有的谷歌搜索和搜索都为我提供了 C++ 和其他而不是 C 的答案。

我的一个想法是将字符串转换为 ASCII,然后将每个 ASCII 值转换为其二进制。 (呃!)我知道这是最愚蠢的想法,但我不确定还有其他选择。

我听说过 Java 中的编码功能。我不确定这是否适合相同的目的并且可以被 C 采用。

string = "Hello"
bytearr[] = 10100101... some byte array..

如果有人能对此有所了解,那就太好了。

谢谢!

【问题讨论】:

  • “二进制字节数组”是什么意思? C 中的“字符串”只是一块内存(数组),其中包含映射到 ASCII 字符的值(字节)。
  • 一些类似于Java中的字节数组的东西。您还可以以字节数组的形式处理字符串。
  • 您似乎对术语感到非常困惑。 C 中的字符串已经是一个二进制字节数组,或多或少是根据定义。而且它可能也已经是 ASCII(除非它是支持 U+0000 到 U+007F 之外的字符的其他 Unicode 编码)。所以请再次尝试解释你希望这个“bytearr”的内容是什么。

标签: c string bytearray


【解决方案1】:

或者您的意思是如何将 C 字符串转换为二进制表示?

这是一种可以将字符串转换为二进制表示的解决方案。可以很容易地更改将二进制字符串保存到字符串数组中。

#include <stdio.h>

int main(int argc, char *argv[])
{
    if(argv[1] == NULL) return 0; /* no input string */

    char *ptr = argv[1];
    int i;

    for(; *ptr != 0; ++ptr)
    {
        printf("%c => ", *ptr);

        /* perform bitwise AND for every bit of the character */
        for(i = 7; i >= 0; --i) 
            (*ptr & 1 << i) ? putchar('1') : putchar('0');

        putchar('\n');
    }

    return 0;
}

输入输出示例:

./ascii2bin hello

h => 01101000
e => 01100101
l => 01101100
l => 01101100
o => 01101111

【讨论】:

    【解决方案2】:

    C 中没有任何字符串。任何字符串都是字节数组。

    【讨论】:

    • 我的意思是“任何字符串都是字节数组。”
    【解决方案3】:

    字符串是字节数组。

    如果您想显示每个字符的 ASCII 值以十六进制形式,您只需执行以下操作:

    while (*str != 0)
      printf("%02x ", (unsigned char) *str++);
    

    【讨论】:

      【解决方案4】:

      在我工作过的大多数系统上,char 的宽度是 1 字节,因此 char[] 或 char* 是字节数组。

      在大多数其他语言(如 Java)中,字符串数据类型在一定程度上通过使用 UTF-8 等编码来处理编码等概念。在 C 中,情况并非如此。如果我要读取内容包含多字节值的 UTF-8 字符串,我的字符将由数组中的 两个 桶表示(或可能更多)。

      从另一个角度来看,考虑到 C 中的所有类型对于您的系统都有固定的宽度(尽管它们可能因实现而异)。

      所以你正在操作的字符串是一个字节数组。

      我想下一个问题是如何显示这些字节?这很简单:

      char* x = ???; /* some string */
      unsigned int xlen = strlen(x);
      int i = 0;
      
      for ( i = 0; i < xlen; i++ )
      {
          printf("%x", x[i]);
      }
      

      我想不出你为什么要将该输出转换为二进制的原因,但如果你有这样的想法,它可以做到。

      【讨论】:

      • 这与“char 的宽度为 1 字节”不太一样,但在这种情况下可能值得再次说一下:sizeof(char)==1 BY DEFINITION。它永远不会是别的东西。 (不过CHAR_BIT的值不一定是8。)
      【解决方案5】:

      如果您只想迭代(或随机访问)单个字节的数值,则根本不需要进行任何转换,因为 C 字符串已经是数组:

      void dumpbytevals(const char *str)
      {
          while (*str)
          {
              printf("%02x ", (unsigned char)*str);
              str++;
          }
          putchar('\n');
      }
      

      但是,如果您对这种代码不小心,当您需要支持非 ASCII 字符时,您可能会陷入困境。

      【讨论】:

        【解决方案6】:

        由于 printf 在转换巨大的二进制数组时速度很慢。这是另一种不使用 printf 的方法:

        #define BASE16VAL               ("x0x1x2x3x4x5x6x7x8x9|||||||xAxBxCxDxExF") 
        #define BASE16_ENCODELO(b)      (BASE16SYM[((uint8)(b)) >> 4])
        #define BASE16_ENCODEHI(b)      (BASE16SYM[((uint8)(b)) & 0xF]) 
        #define BASE16_DECODELO(b)      (BASE16VAL[Char_Upper(b) - '0'] << 4)
        #define BASE16_DECODEHI(b)      (BASE16VAL[Char_Upper(b) - '0']). 
        

        要将十六进制字符串转换为字节数组,您需要执行以下操作:

        while (*Source != 0)   
            {   
            Target[0]  = BASE16_DECODELO(Souce[0]);   
            Target[0] |= BASE16_DECODEHI(Souce[1]);    
        
            Target += 1;   
            Source += 2;   
            } 
        
        *Target = 0;
        

        Source 是指向包含十六进制字符串的 char 数组的指针。 Target 是指向将包含字节数组的 char 数组的指针。

        要将字节数组转换为十六进制字符串,您需要执行以下操作:

        while (*Source != 0)   
            {   
            Target[0] = BASE16_ENCODELO(*Source);   
            Target[1] = BASE16_ENCODEHI(*Source);    
        
            Target += 2;   
            Source += 1;   
            }
        

        Target 是指向包含十六进制字符串的 char 数组的指针。 Source 是指向包含字节数组的 char 数组的指针。

        以下是一些缺少的宏:

        #define Char_IsLower(C)  ((uint8)(C - 'a') < 26)
        #define Char_IsUpper(C)  ((uint8)(C - 'A') < 26)
        #define Char_Upper(C)    (Char_IsLower(C) ? (C + ('A' - 'a')) : C)
        #define Char_Lower(C)    (Char_IsUpper(C) ? (C + ('a' - 'A')) : C)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-25
          • 2015-08-03
          • 2014-06-14
          • 2017-02-23
          • 2014-08-03
          • 2021-02-24
          相关资源
          最近更新 更多