2013-01-03 58 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)