c++ - 从 `stringstream` 读取二进制数据

标签 c++ eof stringstream

更多背景信息,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 

我有两个问题:

  1. 为什么当我执行 ss.get() 时,我必须输入 3 而不是 2,才能一次读取流 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/

相关文章:

c++ - 使用 C++ 使用 “custom” 捕获器创建 WebRTC VideoTrack

c++ - 自定义链表const_iterator不能遍历list的非常量实例

c++ - eof函数如何在cpp上工作?

c++ - ifstream 在 eof 之后仍在读取

c++ - 删除文件的第一行并将其插入回输出中

c++ - 使用图形解决迷宫

c++ - 如何解决,在使用元编程的条件基类的情况下没有成员函数 "print"

c - 我的程序没有找到 EOF 符号

c++ - 为什么 stringstream::str() 会截断字符串?

c++ - 为简单起见,使用来自静态成员函数的 std::stringstream