如何使用指针数组反转数据(解析二进制文件)
我正在使用规范解析二进制文件。该文件采用大端模式,因为它累积了流数据包。我必须反转数据包的长度,以便将它们“reinterpret_cast”为正确的变量类型。 (我无法使用 net/inet.h 函数,因为数据包具有不同的长度)。
ifstream 类的 read() 方法将字节放入图表指针数组中。我尝试使用 a 手动进行还原,但我无法弄清楚如何传递“指针列表”以更改它们在数组中的位置。
如果有人知道更有效的方法,请告诉我(需要解析 8GB 数据)。
#include <iostream>
#include <fstream>
void reverse(char &array[]);
using namespace std;
int main ()
{
char *a[5];
*a[0]='a'; *a[1]='b'; *a[2]='c'; *a[3]='d'; *a[4]='e';
reverse(a);
int i=0;
while(i<=4)
{
cout << *a[i] << endl;
i++;
}
return 0;
}
void reverse(char &array[])
{
int size = sizeof(array[])+1;
//int size = 5;
cout << "ARRAY SIZE: " << size << endl;
char aux;
for (int i=0;i<size/2;i++)
{
aux=array[i];
array[i]=array[size-i-1];
array[size-i-1]=aux;
}
}
感谢大家的帮助!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不完全是。
您需要在存储数据级别反转字节,而不是文件或数据包。
例如,如果一个文件存储一个结构体。
要读取该结构,您需要反转:
不是一次读取整个结构。
不幸的是,它并不像反转文件中的数据块或文件本身那么简单。您需要确切地知道正在存储什么数据类型,并反转其中的字节。
inet.h
中的函数正是用于此目的,因此我鼓励您使用它们。那么,这就引出了 C 字符串。如果您将 C 字符串存储在文件中,是否需要交换它们的字节顺序?嗯,ac 字符串是 1 字节 char 的序列。您不需要交换 1 个字节的
char
,因此您不需要交换 ac 字符串中的数据!如果您确实想交换 6 个字节,则可以使用 std::reverse 函数:
如果您要大规模(大量类型)执行此操作,那么您可能需要考虑编写一个代码生成器来生成这些字节交换函数(和文件读取函数),这并不太难,只要你能找到一个工具来解析c中的结构(我使用过gcc-xml 为此,或者可能 clang 会有所帮助)。
这使得序列化成为一个更难的问题。如果您有能力,您可能需要考虑使用 XML 或 Google 的协议缓冲区来为您解决这些问题。
Not quite.
You need to reverse the bytes on the level of stored data, not the file and not the packets.
For example, if a file stores a struct.
to read the struct you will need to reverse:
Not the entire struct at once.
Unfortunately, it's not as trivial as just reversing the block of data in the file, or the file itself. You need to know exactly what data type is being stored, and reverse the bytes in it.
The functions in
inet.h
are used for exactly this purpose, so I encourage you to use them.So, that brings us to c strings. If you're storing c strings in a file, do you need to swap their endianness? Well, a c string is a sequence of 1 byte
char
s. You don't need to swap 1 bytechar
s, so you don't need to swap the data in a c string!If you really want to swap 6 bytes, you can use the
std::reverse
function:If you're doing this on any large scale (a large amount of types), then you may want to consider writing a code generator that generates these byte swapping functions (and file reading functions), it's not too hard, as long as you can find a tool to parse the structs in c (I've used gcc-xml for this, or maybe clang would help).
This makes serialization a harder problem. If it's in your power, you may want to consider using XML or Google's protocol buffers to solve these problems for you.
好吧,听完你的评论我明白你在追求什么了。因此,您需要更改 6 字节宽的字段的字节顺序。
我认为这篇文章应该对您有帮助这个问题关于SO,它展示了如何实现以不同的方式进行转换,最快的是按位实现。它没有显示六字节宽字段的实现,但可以轻松制定类似的解决方案。
我建议将长度字段复制为 64 位整数,然后实现自定义函数来交换相关的 6 个字节。在任何情况下摆脱或所有字符指针...;)
如果您在 VC++ 上编译,则有此函数: _byteswap_uint64。超过这个 uint64 高端的 6 个字节,调用这个函数和 hopla,你就完成了。
凌晨 4:12 编辑(我一定是对 stackoverflow 非常上瘾了)
Ok, after your comment I understand what you are after. So you need to change endianness of a field that is 6 bytes wide.
I think this article should help you as well as this question on SO, it shows how to implement conversions in different ways, the fastest being a bitwise implementation. It shows no implementation for a six byte wide field, but an analogous solution can easily be made.
I suggest copying your length field in a 64bit integer and then implementing a custom function to swap the relevant 6 bytes. Get rid or all the char pointers in any case...;)
If you are compiling on VC++ there is this function: _byteswap_uint64. Past your 6 bytes in the high end of this uint64, call this function and hopla, you are done.
edit at 4:12 am (I must be getting very addicted to stackoverflow)