2

我有以下内容:

boost::uint32_t data[ 256 ];
fillMyArray( data );

std::ofstream output( "this.raw", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc );
output.write( reinterpret_cast< char * >( & data ), 256 * 4 );
output.close( );

但是,数组将以本地字节顺序保存。如何确保它将以 little endian 存储?如果更简单,我可以使用 Boost 库。

4

4 回答 4

6

使用karma::big_wordorkarma::little_word可能是一个选项:

在 Coliru上现场观看

输出/a.out && xxd this.raw

0000000: f000 f001 f002 f003 f004 f005 f006 f007  ................
0000010: f008 f009 f00a f00b f00c f00d f00e f00f  ................
0000020: f010 f011 f012 f013 f014 f015 f016 f017  ................
0000030: f018 f019 f01a f01b f01c f01d f01e f01f  ................
0000040: f020 f021 f022 f023 f024 f025 f026 f027  . .!.".#.$.%.&.'
// ...
0000200: 00f0 01f0 02f0 03f0 04f0 05f0 06f0 07f0  ................
0000210: 08f0 09f0 0af0 0bf0 0cf0 0df0 0ef0 0ff0  ................
0000220: 10f0 11f0 12f0 13f0 14f0 15f0 16f0 17f0  ................
0000230: 18f0 19f0 1af0 1bf0 1cf0 1df0 1ef0 1ff0  ................
0000240: 20f0 21f0 22f0 23f0 24f0 25f0 26f0 27f0   .!.".#.$.%.&.'.

完整代码:

#include <boost/spirit/include/karma.hpp>
#include <fstream>

namespace karma = boost::spirit::karma;

template <typename C>
void fillMyArray(C& data) 
{
    std::iota(begin(data), end(data), 0xf000);
}


int main()
{
    std::vector<boost::uint32_t> data(256);
    fillMyArray(data);

    std::ofstream output( "this.raw", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc );
    boost::spirit::karma::ostream_iterator<char> outit(output);

    karma::generate(outit, +karma::big_word,    data);
    karma::generate(outit, +karma::little_word, data);
}
于 2013-08-18T15:01:35.443 回答
1

我认为这可以分为三个问题阶段:

  1. 确定系统是小端还是大端。有很多方法可以做到这一点,运行时或编译时间(通常,编译时间很好)。
  2. 进行转换(如果需要)。
  3. 写入数据。

对于 1. boost 具有endian.hpp为大多数设置提供此功能的 a - 它定义BOOST_BIG_ENDIANBOOST_LITTLE_ENDIAN.

在 2 的情况下,遍历缓冲区并就地复制或转换。大多数编译器都有一个内置函数来交换数据的字节,MSVC 提供_byteswap_ulong并且 GCC 有__builtin_bswap32- 对于其他编译器,请查看它们各自的文档。

如果字节交换“就地”完成,则第 3 部分不需要更改。如果是副本,显然应该将字节交换数据提供给write.

于 2013-08-15T12:27:05.893 回答
0

虽然它不会在一次调用中写入所有数据,但您可以使用 egstd::transform来写入值:

std::transform(std::begin(data), std::end(data)
               std::ostream_iterator<uint32_t>(output),
               [](const uint32_t& value) -> uint32_t {
                   return convert_endianess(value);
               });

其中convert_endianess函数是进行字节序转换的函数。

于 2013-08-15T12:16:41.480 回答
0

Joachim Pileborg 给出了一个很好的答案。除了编写自己的函数之外,您还可以使用此处描述的 std::reverse() How to manage endianess of double from network

于 2013-08-18T12:23:17.620 回答