c++ - 为什么 std::ostreambuf_iterator 截断整数?

标签 c++ stl

我正在通过 std::copy(numbers.begin(), numbers.end(), std::ostreambuf_iterator<char>{stream}) 将 uint32_t 数字的排序 vector 复制到二进制流中, 但它会截断数字,将它们变成 1 字节数字。

我的代码有什么问题?我有一个解决方法,但也许可以使 ostreambuf_iterator 方法正常工作?

std::ofstream chunk{ "filename.txt", std::ios::binary | std::ios::out };

// this piece of code works not expected
std::copy(numbers.begin(), numbers.end(), std::ostreambuf_iterator<char>{chunk});

// But this, alternative works good
for (auto& v : numbers)
    chunk.write((char*)& v, sizeof uint32_t);

我希望得到这样的输出:

0000 0000 0000 0000 0000 0000 0100 0000
0100 0000 0100 0000 0100 0000 0100 0000

但我的输出是:

0000 0000 0000 0000 0000 0000 0101 0101
0101 0101 0101 0101 0101 0101 0101 0101

最佳答案

I'm copying a sorted vector of uint32_t numbers into a binary stream via std::copy(numbers.begin(), numbers.end(), std::ostreambuf_iterator<char>{stream}), but it truncates numbers, turns them into 1-byte numbers.

是的——您要求它这样做!

您的范围是 uint32_t , 那么你使用的是 char迭代器。

所以每个元素都被转换成一个char随着它的进行。

std::ostreambuf_iterator<char>不会自动为不同类型的输入元素起别名。这在大多数情况下是非法的,而且它必须进行缓冲以(在本例中)为每个输入提供四个输出:现在假设您提供了 char s 到 ostreambuf_iterator<uint32_t> ,并意识到它必须为每四个输入提供一个输出,这变得更加复杂。这不是这个迭代器的用途。

您需要将该范围视为 char 的范围反而;幸运的是,由于别名豁免,这是合法的。我们不能再使用 vector 迭代器了,但这没关系,因为我们可以直接访问指针形式的连续数据,并用这些指针做我们想做的事:

std::copy(
   reinterpret_cast<const char*>(numbers.data()),
   reinterpret_cast<const char*>(numbers.data() + numbers.size()),
   std::ostreambuf_iterator<char>{stream}
);

这实际上等同于您的第二个示例。

关于c++ - 为什么 std::ostreambuf_iterator 截断整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58730979/

相关文章:

c++ - 使用 nullptr 作为 std::unordered_map 的键有什么后果吗?

c++ - protected 成员与重载运算符冲突

c++ - 将对象传递给重载运算符

c++ - 在 C++ 中使用 map 时输出顺序错误

c++ - STL for_each 提示参数列表

c++ - std::map clear() 在调试器中的性能?

c++ - g++ v 3.4.4-999 中的 unordered_map::emplace 错误

c++ - auto的推导使编译器生成默认构造函数

使用STL和Arima的R预测季节和数据趋势

c++ - 后缀表达式求值