2012-01-16 57 views
3

說,我有二進制協議,其中前4位表示可以小於或等於10(十進制十)的數值。如何在C++中以二進制格式打包數據

在C++中,可用於我的最小數據類型是char,它是8位長。所以,在我的應用程序中,我可以在char變量中保存由4位表示的值。我的問題是,如果我必須將char值打包回4位進行網絡傳輸,我如何將我的char值再打包回4位?

+3

請參閱http://stackoverflow.com/questions/443265/where-can-i-find-a-bit-shifting-guide-for -c – 2012-01-16 22:48:05

回答

3

當然,只使用一個字符爲你的價值:

std::ofstream outfile("thefile.bin", std::ios::binary); 

unsigned int n; // at most 10! 
char c = n << 4; // fits 
outfile.write(&c, 1); // we wrote the value "10" 

下4位會在零留下。如果它們也用於某些事情,則在寫入之前,必須完全填充c。閱讀:

​​
+0

n << 4將n移位4這意味着它將使用「更重要」位。數字是8或9的問題是它將使用最重要的位。因此,我的建議是使用「無符號字符」,尤其是回讀。 – CashCow 2012-01-16 23:22:25

+0

以上是寫8位..我的問題是,我怎麼寫只有4位到輸出流在C + + – Jimm 2012-01-16 23:51:51

+0

@Jimm:自然,你不能,因爲最小的可尋址單位是一個'字符'。然而,您可以*先讀取*一個字節,只處理其高四位,並將結果寫回。 – 2012-01-17 01:10:05

4

你對char進行按位運算;

所以

unsigned char packedvalue = 0; 

    packedvalue |= 0xF0 & (7 <<4); 
    packedvalue |= 0x0F & (10); 

設置4最高位7和低4位至10

這些再次開箱作爲

int upper, lower; 

upper = (packedvalue & 0xF0) >>4; 
lower = packedvalue & 0x0F; 

作爲一個額外的問題的答案 - - 您也可以查看protocol buffers以獲取二進制傳輸數據的編碼和解碼方法。

+0

恢復值時,需要注意簽名。 – 2012-01-16 22:55:28

+0

@Ben,只要你打包正數,無符號字符應該照顧 - 但是如果你計劃打包一個負數 - (比如-2)到一個位字段,那麼你可能需要做一些更多的代碼。 – Soren 2012-01-16 22:59:22

+0

爲什麼我需要做0xF0&(7 << 4),當它產生與7 << 4相同的結果? – Jimm 2012-01-16 23:22:38

3

那麼,有流行的,但不便攜的「位場」。它們符合標準,但可以在不同平臺上創建不同的打包順序。所以不要使用它們。

然後,有高度便攜的位移和按位AND和OR操作符,您應該更喜歡。本質上,你在一個更大的領域工作(通常是TCP/IP協議的32位)並提取或替換位的子序列。請參閱Martin的鏈接和Soren的答案。

0

您是否熟悉C's bitfields?您只需編寫

struct my_bits { 
    unsigned v1 : 4; 
    ... 
}; 

被警告,各種操作都在位域慢,因爲編譯器必須解開他們的東西像加法。我想可以解開一個位域,雖然它需要多條指令,但它仍然會比添加操作本身更快,但它仍然是開銷。按位操作應該保持相當快。平等也是如此。

你還必須注意排序和線程(請參閱維基百科的文章我鏈接的細節,但問題是顯而易見的)。無論如何,你應該從字節序列中學習,因爲你說「二進制協議」(見this previous questions

+0

或者你真的應該簡單地使用協議緩衝包Soren指出。 – 2012-01-17 00:07:35

相關問題