2011-07-01 129 views
1

我想从UTF-8格式中提取字符值。假设我有两个字符,并予提取第一个字符5个比特=> 10111和6位与另一个字符=> 010000C++位操作

所以

ch1 = 10111; 
ch2 = 010000; 

我将如何将它们合并以形成10111010000和输出其十六进制为0x5d0?我是否需要移位或是否有更简单的方法来执行此操作,因为检查文档write似乎能够按顺序读取字符,是否有类似的功能?此外,它似乎我需要一个字符缓冲区,因为10111010000是11位长。有没有人知道如何去做这件事?

+0

如何使用'union'?您可能需要格外小心,因为它们的对齐可能取决于平台。 – iammilind

+0

@iammilind我将如何使用union?你能否详细说明答案? – Mark

回答

3

您需要使用移位,加上||=运算符。

unsigned int ch3 = (ch1 << 6) | ch2; 
// ch3 = 0000010111010000 

我在这里假设unsigned int是16位。你的旅费可能会改变。

+0

我最多需要21位才能读取最大的utf8。我会怎么做? – Mark

+1

然后,以十六进制打印,'std :: cout << std :: showbase << std :: hex;' – juanchopanza

+2

@Mark我会研究['std :: bitset'](http:// www .cplusplus.com /参考/ STL /位集/)。或者,你可以使用'unsigned long int',它保证至少有32位。 – Maxpm

2

您一定需要使用shift和OR。

首先,声明一个正确大小的无符号整数类型。我喜欢在stdint.h中定义的C99类型,但是你的C++编译器可能没有它们。如果您没有uint16_t,那么您可以使用unsigned short。这是16位宽,可以保存11位。

然后你会找出哪些位进入高位。它看起来应该是:

unsigned short ch1 = 0x17; 
unsigned short ch2 = 0x10; 
unsigned short result = (ch1 << 6) | ch2; 
+0

最大的提取需要高达21位。我需要一个字符缓冲区[]吗? – Mark

+0

@Mark,不,看到这个线程:http://stackoverflow.com/questions/589575/c-size-of-int-long-etc。据此,该标准要求'unsigned long'为32位。 – juanchopanza

0

1:将它们组合在一起:

char bytes[2] = { 0x17, 0x10 }; // for example 

unsigned short result = 0;  // 00000000 00000000 
result = bytes[0] << 6;   // 101 11000000 
result |= bytes[1];    // 101 11010000 

2:在这种情况下,打印出来的十六进制

std::cout << std::showbase << std::hex << <what you want to print>; 

std::cout << std::showbase << std::hex << result 
// output: 0x5d0 if it is little-endian, it depends on your operating system 
0

首先,从K & R:“几乎所有关于位域的东西都依赖于实现”。

在微软的Visual Studio 2008中的以下工作:

#include <stdio.h> 
#include <string.h> 

struct bitbag { 
    unsigned int ch2 : 6; 
    unsigned int ch1 : 6; 
}; 

int main() 
{ 
    struct bitbag bits; 

    memset(&bits, 0, sizeof(bits)); 

    bits.ch1 = 0x17; // 010111 
    bits.ch2 = 0x10; // 010000 

    printf ("0x%06x 0x%06x\n", bits.ch1, bits.ch2); 
    printf ("0x%0x\n", bits); 

    return 0; 
} 

产生输出:

0x000017 0x000010 
0x5d0 

但是我无法机制保障,它会在所有的编译器相同的方式工作。请注意0​​将任何填充初始化为零。

+0

然后在一个struct上做一个printf ......不保证它能正常工作。 –

+0

此外,您需要UTF-8的“可变位宽”,位布局取决于第一个字节。而那些根本不存在。 – MSalters