2011-07-01 176 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