将C++数组转储到具有特定endianness的文件中
Dumping a C++ array into a file with a certain endianness
我有如下内容:
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库。
使用karma::big_word
或karma::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);
}
我认为这可以分为三个问题阶段:
- 确定系统是小端还是大端。有很多方法可以做到这一点,运行时或编译时(通常,编译时是可以的)
- 进行转换(如果需要)
- 写入数据
对于1。boost有一个endian.hpp
,它为大多数设置提供了这一功能——它定义了BOOST_BIG_ENDIAN
或BOOST_LITTLE_ENDIAN
。
在2的情况下,在缓冲区上迭代,然后就地复制或转换。大多数编译器都有一个内置的函数来交换数据的字节,MSVC提供_byteswap_ulong
,GCC提供__builtin_bswap32
。对于其他编译器,请查看各自的文档。
对于第3部分,如果字节交换是"就地"完成的,则不需要更改。如果它是一个副本,那么显然应该将字节交换的数据提供给write
。
虽然它不会在一个调用中写入所有数据,但您可以使用例如std::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
函数是用于进行字节序转换的函数。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 处理endianness和文件C 的最常见方法
- 将C++数组转储到具有特定endianness的文件中