从二进制文件读取时将大端转换为小端
我一直在研究如何将大端转换为小端。但我没有找到任何可以解决我的问题的好方法。似乎有很多方法可以进行这种转换。无论如何,下面的代码在大端系统中工作正常。但是我应该如何编写一个转换函数,以便它也能在小端系统上工作?
这是一项作业,但它只是一个额外的作业,因为学校的系统运行的是大端系统。只是我很好奇,想让它在我的家用电脑上工作也
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream file;
file.open("file.bin", ios::in | ios::binary);
if(!file)
cerr << "Not able to read" << endl;
else
{
cout << "Opened" << endl;
int i_var;
double d_var;
while(!file.eof())
{
file.read( reinterpret_cast<char*>(&i_var) , sizeof(int) );
file.read( reinterpret_cast<char*>(&d_var) , sizeof(double) );
cout << i_var << " " << d_var << endl;
}
}
return 0;
}
已解决
所以Big-endian VS Little-endian只是字节的相反顺序。无论如何,我写的这个函数似乎达到了我的目的。我将其添加在这里,以防将来其他人需要它。这仅适用于双精度,对于整数,可以使用 torak 建议的函数,也可以通过使其仅交换 4 个字节来修改此代码。
double swap(double d)
{
double a;
unsigned char *dst = (unsigned char *)&a;
unsigned char *src = (unsigned char *)&d;
dst[0] = src[7];
dst[1] = src[6];
dst[2] = src[5];
dst[3] = src[4];
dst[4] = src[3];
dst[5] = src[2];
dst[6] = src[1];
dst[7] = src[0];
return a;
}
I've been looking around how to convert big-endian to little-endians. But I didn't find any good that could solve my problem. It seem to be there's many way you can do this conversion. Anyway this following code works ok in a big-endian system. But how should I write a conversion function so it will work on little-endian system as well?
This is a homework, but it just an extra since the systems at school running big-endian system. It's just that I got curious and wanted to make it work on my home computer also
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream file;
file.open("file.bin", ios::in | ios::binary);
if(!file)
cerr << "Not able to read" << endl;
else
{
cout << "Opened" << endl;
int i_var;
double d_var;
while(!file.eof())
{
file.read( reinterpret_cast<char*>(&i_var) , sizeof(int) );
file.read( reinterpret_cast<char*>(&d_var) , sizeof(double) );
cout << i_var << " " << d_var << endl;
}
}
return 0;
}
Solved
So Big-endian VS Little-endian is just a reverse order of the bytes. This function i wrote seem to serve my purpose anyway. I added it here in case someone else would need it in future. This is for double only though, for integer either use the function torak suggested or you can modify this code by making it swap 4 bytes only.
double swap(double d)
{
double a;
unsigned char *dst = (unsigned char *)&a;
unsigned char *src = (unsigned char *)&d;
dst[0] = src[7];
dst[1] = src[6];
dst[2] = src[5];
dst[3] = src[4];
dst[4] = src[3];
dst[5] = src[2];
dst[6] = src[1];
dst[7] = src[0];
return a;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用一个模板进行字节序交换,该模板将针对数据类型进行概括:
然后您的代码最终将类似于:
You could use a template for your endian swap that will be generalized for the data types:
Then your code would end up looking something like:
您可能对
ntohl
函数系列感兴趣。它们旨在将数据从网络字节顺序转换为主机字节顺序。网络字节顺序是大尾数,因此在大尾数系统上它们不执行任何操作,而在小尾数系统上编译的相同代码将执行适当的字节交换。You might be interested in the
ntohl
family of functions. These are designed to transform data from network to host byte order. Network byte order is big endian, therefore on big endian systems they don't do anything, while the same code compiled on a little endian system will perform the appropriate byte swaps.Linux 提供了
endian.h
,它具有高达 64 位的高效字节序交换例程。它还会自动考虑系统的字节顺序。 32 位函数的定义如下:16 位和 64 位的函数具有类似名称。
所以你只要说
将little-endian编码的32位整数转换为主机CPU编码。这对于读取小端数据很有用。
将从主机编码转换为 32 位小端编码。这对于写入小端数据很有用。
注意,在 BSD 系统上,等效的头文件是 sys/endian.h
Linux provides
endian.h
, which has efficient endian swapping routines up to 64-bit. It also automagically accounts for your system's endianness. The 32-bit functions are defined like this:with similarly-named functions for 16 and 64-bit.
So you just say
to convert a 32-bit integer in little-endian encoding to the host CPU encoding. This is useful for reading little-endian data.
will convert from the host encoding to 32-bit little-endian. This is useful for writing little-endian data.
Note on BSD systems, the equivalent header file is
sys/endian.h
假设您要继续,保留一个辅助函数的小库文件会很方便。其中 2 个函数应该是 4 字节值和 2 字节值的字节序交换。有关一些可靠的示例(包括代码),请查看这篇文章。
获得交换函数后,每当您以错误的字节序读入值时,请调用适当的交换函数。有时,这里的人们的一个绊脚石是单字节值不需要进行字节序交换,因此,如果您正在读取代表文件中字母字符串的字符流之类的内容,那么应该很好。只有当您读取多个字节的值(如整数值)时,您才必须交换它们。
Assuming you're going to be going on, it's handy to keep a little library file of helper functions. 2 of those functions should be endian swaps for 4 byte values, and 2 byte values. For some solid examples (including code) check out this article.
Once you've got your swap functions, any time you read in a value in the wrong endian, call the appropriate swap function. Sometimes a stumbling point for people here is that single byte values do not need to be endian swapped, so if you're reading in something like a character stream that represents a string of letters from a file, that should be good to go. It's only when you're reading in a value this is multiple bytes (like an integer value) that you have to swap them.
值得补充的是,MS 在 VS 上也支持此功能,请检查此内联函数:
It is good to add that MS has this supported on VS too check this inline functions: