2013-01-03 152 views
0

更多的背景,see here讀取二進制數據`stringstream`

我使用的是stringstream通過二進制數據讀取。到目前爲止,我只是寫一個虛擬程序來讓課堂感到舒適。這是我的計劃:

#include <sstream> 
#include <iostream> 
#include <iomanip> 
#include <cstdio> 

using namespace std; 

string bytes2hex(char* bytes, int n){ 
    stringstream out; 
    for (int i = 0;i < n;i++){ 
     out << setfill ('0') << setw(2) << hex << (int) bytes[i] << " "; 
    } 

    string st = out.str(); 
    for(short k = 0; k < st.length(); k++) 
    { 
     st[k] = toupper(st[k]); 
    } 

    return st; 
} 

int main(){ 
    stringstream ss; 

    ss << "hello the\0re my\0\0\0 friend"; 

    while (ss.peek() != EOF){ 
     char buf [2]; 
     ss.get(buf, 3); 
     cout << buf << "\t==>\t" << bytes2hex(buf, 2) << endl; 
    } 
} 

輸出:

he ==> 68 65 
ll ==> 6C 6C 
o ==> 6F 20 
th ==> 74 68 
e ==> 65 00 
    ==> 00 00 

我對此有2個問題:

  1. 爲什麼,當我執行ss.get(),我要輸入3,而比2,一次讀取流2個字符?
  2. 它爲什麼終止於第一個空字符,我如何防止這種情況發生?
+0

相關http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong –

回答

2

關於第一個問題:
istream::get要形成什麼讀取一個有效的C風格的字符串,所以它被指定閱讀比您傳遞的緩衝區大小更小的一個字符,並將'\0'字符存儲在最後位置。
實際上,你也應該將buf擴展爲3個字節長,所以ss.get將會保持在邊界內。

關於第二個問題:
在第一個'\0'字符發生的截斷髮生在插入到字符串流中。原因是,當你插入一個C風格的字符串(並且包含字符串文字)時,代碼將停止在第一個'\0'字符處處理它,因爲這是C風格字符串的定義。

您可以用這種方法數據正確填寫您的字符串流:

ss << string("hello the\0re my\0\0\0 friend", 25); 

其中25來自你的二進制輸入的長度。

1

istream.get用於讀取文本數據,當讀取到n-1個字符時讀取停止,或遇到\n。如果你想讀的二進制數據,然後使用此:

ss.read(buf, 2)