2011-04-14 91 views
2

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

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

我听说过abt Java中的编码函数。我不知道是否适合同样的目的,可以采用C.

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

这将是巨大的,如果有人能在此抛出一些轻。

谢谢!

+2

你所说的“二进制字节数组”是什么意思? C中的“String”只是一个包含值(字节)的内存块(数组),它被映射为ASCII字符。 – 2011-04-14 17:08:32

+0

有些东西与Java中的字节数组相似。你还可以以字节数组的形式处理字符串。 – Maverickgugu 2011-04-14 17:10:47

+1

您似乎对术语非常困惑。 C *中的字符串已经是一个二进制字节数组,或多或少的定义。它可能也已经是ASCII码(除非它是Unicode的其他编码,它支持U + 0000到U + 007F以外的字符)。所以请再次尝试解释你想要这个“bytearr”的内容。 – zwol 2011-04-14 17:11:27

回答

8

还是你的意思是如何将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 
3

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

+0

我的意思是“任何字符串都是字节数组”。 – Jurlie 2011-04-14 17:14:02

+1

修复了这个问题 – 2011-04-14 17:16:28

0

如果你只是想迭代(或随机访问)单个字节数值,你不必做任何转换可言,因为C字符串是数组已经:

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

如果”不过,对于这类代码不要小心,但是当您需要支持非ASCII字符时,您有可能处于受伤的世界。

1

字符串字节数组。

如果你想显示以十六进制形式的每个字符的ASCII值,你只会做这样的事情:

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

在大多数我曾在系统中,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]); 
} 

我想不出有任何理由为什么你要到输出转换为二进制的,但如果你是如此的胸襟这是可以做到。

+1

这和'char'的宽度是1个字节不太一样,但它可能值得再次在这个上下文中说:'sizeof(char)== 1' BY DEFINITION。它永远不会是别的。 (然而,'CHAR_BIT'的值不一定是8.) – zwol 2011-04-14 17:19:12

0
由于

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; 

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

字节数组转换为十六进制字符串你会于以下内容:

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

    Target += 2; 
    Source += 1; 
    } 

目标是一个指向包含一个十六进制字符串字符数组。 源是指向包含字节数组的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) 
相关问题