我正在通过 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/