更多背景信息,see here
我正在使用 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
我有两个问题:
- 为什么当我执行
ss.get()
时,我必须输入 3 而不是 2,才能一次读取流 2 个字符? - 为什么它在第一个空字符处终止,我该如何防止这种情况发生?
最佳答案
关于第一个问题:
istream::get
想要将其读取的内容形成一个有效的 C 风格字符串,因此指定读取比您传递的缓冲区大小少一个字符,并在最后位置存储一个 '\0'
字符。< br/>
实际上,您还应该将 buf
扩展为 3 个字节长,这样 ss.get
将保持在范围内。
关于第二个问题:
第一个 '\0'
字符处的截断已经发生在插入到字符串流中时。原因是,当您插入 C 风格的字符串(包括字符串文字)时,代码会在第一个 '\0'
字符处停止处理它,因为这是 C 的定义-风格的字符串。
您可以通过这种方式用数据正确填充您的字符串流:
ss << string("hello the\0re my\0\0\0 friend", 25);
25
来自二进制输入的长度。
关于c++ - 从 `stringstream` 读取二进制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14143249/