用于二进制输出的 ostream_iterator

Jon*_*Mee 3 c++ file-io iterator fstream binaryfiles

我希望能够使用ostream_iterator流式传输到二进制文件。但是ostream_iterator使用FormattedOuputFunction所以它会写 ASCII,而不是二进制:

std::ostream_iterator是一个单通道 OutputIterator,它使用类型将连续的对象写入构造它Tstd::basic_ostream对象中,使用operator<<

除了编写我自己的迭代器之外,还有没有办法使用迭代器来编写二进制文件?

我正在尝试做的一个简化示例,但该copy语句会将 ASCII 写入我的二进制文件:

ofstream foo("foo.txt", ios_base::binary);
vector<int> bar = {13, 42};

copy(bar.cbegin(), bar.cend(), ostream_iterator<decltype(bar)::value_type>(foo));
Run Code Online (Sandbox Code Playgroud)

Pot*_*ter 5

ostreambuf_iterator比 更合适ostream_iterator。它的重量要轻得多,并且不进行格式化。它采用字符类型的模板参数,因此与大多数流兼容的唯一选择是std::ostream_iterator< char >.

确保以二进制模式打开流。顺便说一下,标准流缓冲区永远不会以二进制模式打开。


Ser*_*sta 2

它可以工作,但是您必须明确使用ostream_iterator<char>.

示例(为了简洁而省略):

int main(int argc, char **argv) {
    std::vector<int> arr;

    std::ofstream fd("foo.txt", std::ios::binary | std::ios::out);

    for (int i=0; i<256; i++) arr.push_back(i);

    std::ostream_iterator<char> oi(fd);
    std::copy(arr.begin(), arr.end(), oi);
    fd.close();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

将在 foo.txt 中写入 0 到 255 的 256 个字节。


上面假设您想​​将 int 的值作为 char 直接写入文件。根据您的评论,您希望以本机主机字节序将 int 值写入 4 字节值(假设 int32_t)。我会使用辅助类来完成这项工作:

class bint {
private:
    char c[sizeof(int)];

public:
    bint(const int i) { // allows bint b = 5;
        ::memcpy(c, &i, sizeof(c));
    }
    operator int() const {  // allows : bint b = 5; int i=b => gives i=5
        int i;
        ::memcpy(&i, c, sizeof(int));
        return i;
    }
    const char *getBytes() const { // gives public read-only access to the bytes
        return c;
    }
};

std::ostream& operator <<(std::ostream& out, const bint& b) {
    out.write(b.getBytes(), sizeof(int));
    return out;
}

int main(int argc, char **argv) {
    std::vector<int> arr;

    std::ofstream fd("foo.txt", std::ios::binary | std::ios::out);

    for (int i=0; i<256; i++) arr.push_back(i);

    std::ostream_iterator<bint> oi(fd);
    std::copy(arr.begin(), arr.end(), oi);
    fd.close();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个写入 1024 个字节(对于大小为 4 的整数),其中包含前 256 个整数的表示。它会自动适应其他大小的 int。