C ++中是否有二进制内存stream?

我通常使用stringstream来写入内存中的string。 有没有办法写入二进制模式的字符缓冲区? 考虑下面的代码:

 stringstream s; s << 1 << 2 << 3; const char* ch = s.str().c_str(); 

ch的内存将如下所示:0x313233 – 字符1,2和3的ASCII代码。我正在寻找一种方法来编写二进制值本身。 也就是说,我想在内存中的0x010203。 问题是我想能够写一个函数

 void f(ostream& os) { os << 1 << 2 << 3; } 

并决定在什么样的stream使用。 像这样的东西:

 mycharstream c; c << 1 << 2 << 3; // c.data == 0x313233; mybinstream b; b << 1 << 2 << 3; // b.data == 0x010203; 

有任何想法吗?

要读取二进制数据并将其写入stream(包括stringstream),请使用read()和write()成员函数。 所以

 unsigned char a(1), b(2), c(3), d(4); std::stringstream s; s.write(reinterpret_cast<const char*>(&a), sizeof(unsigned char)); s.write(reinterpret_cast<const char*>(&b), sizeof(unsigned char)); s.write(reinterpret_cast<const char*>(&c), sizeof(unsigned char)); s.write(reinterpret_cast<const char*>(&d), sizeof(unsigned char)); s.read(reinterpret_cast<char*>(&v), sizeof(unsigned int)); std::cout << std::hex << v << "\n"; 

这给我的系统0x4030201

编辑:为了使插入和提取操作符(<<和>)透明地工作,最好的办法是创build一个派生的streambuf来执行正确的操作,并将其传递给您想要使用的任何stream。

那么,只是使用字符,而不是整数。

 s << char(1) << char(2) << char(3); 

超载一些不寻常的操作员工作得很好。 下面我select重载<=,因为它具有与<<左右相关的相同性,并且具有某种亲密的外观和感觉。

 #include <iostream> #include <stdint.h> #include <arpa/inet.h> using namespace std; ostream & operator<= (ostream& cout, string const& s) { return cout.write (s.c_str(), s.size()); } ostream & operator<= (ostream& cout, const char *s) { return cout << s; } ostream & operator<= (ostream&, int16_t const& i) { return cout.write ((const char *)&i, 2); } ostream & operator<= (ostream&, int32_t const& i) { return cout.write ((const char *)&i, 4); } ostream & operator<= (ostream&, uint16_t const& i) { return cout.write ((const char *)&i, 2); } ostream & operator<= (ostream&, uint32_t const& i) { return cout.write ((const char *)&i, 4); } int main() { string s("some binary data follow : "); cout <= s <= " (machine ordered) : " <= (uint32_t)0x31323334 <= "\n" <= s <= " (network ordered) : " <= htonl(0x31323334) ; cout << endl; return 0; } 

有几个缺点:

  • <=的新含义可能会使读者感到困惑或导致意想不到的结果:

     cout <= 31 <= 32; 

    将不会给出相同的结果

     cout <= (31 <= 32); 
  • 如上例所示,在阅读代码时,没有明显提到Endianess。

  • 它不能简单地与<<混合,因为它不属于同一组优先。 我通常使用括号来澄清如:

     ( cout <= htonl(a) <= htonl(b) ) << endl; 

对于这个用例,我实现了一个“原始转换运算符”:

 template <typename T, class... StreamArgs> inline std::basic_ostream<StreamArgs...> & operator <= (std::basic_ostream<StreamArgs...> & out, T const & data) { out.write(reinterpret_cast<char const *>(&data), sizeof(T)); return out; } 

把它放在方便的地方,像这样使用它:

 std::cout <= 1337 <= 1337ULL <= 1337. <= 1337.f; 

优点:

  • 可链接
  • 自动sizeof()
  • 同样需要数组和结构/类实例

缺点:

  • 对非POD对象不安全:泄漏指针和填充
  • 输出是平台特定的:填充,字节数,整数types