为什么std :: ostreambuf_iterator截断整数?

问题描述 投票:0回答:1

我正在通过std::copy(numbers.begin(), numbers.end(), std::ostreambuf_iterator<char>{stream})将uint32_t数字排序后的向量复制到二进制流中,但是它会截断数字,将其变成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
c++ stl
1个回答
3
投票

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

是的-您要求这样做!

您有一个uint32_t范围,那么您正在使用char迭代器。

因此每个元素在通过时都会转换为char

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

您将要将该范围视为char的范围;幸运的是,由于免除别名,这是合法的。我们不能再使用向量迭代器,但这很好,因为我们可以以指针的形式直接访问其连续数据,并使用这些指针做我们喜欢的事情:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.