[英]How to reverse data using an array of pointers (parse binary file)
我正在使用規范解析二進制文件。 該文件采用大端模式,因為它已累積了流式傳輸的數據包。 我必須反轉數據包的長度,以便將它們“ 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;
}
}
謝謝大家的幫助!
不完全的。
該文件采用大端模式,因為它已累積了流式傳輸的數據包。 我必須反轉數據包的長度,以便將它們“ reinterpret_cast”轉換為正確的變量類型。
您需要反轉存儲數據級別的字節,而不是文件而不是數據包。
例如,如果文件存儲結構。
struct S {
int i;
double d;
char c;
};
閱讀該結構,您將需要反轉:
int: [4321]->[1234] // sizeof(int) == 4, swap the order of 4 bytes
double: [87654321]->[12345678] // sizeof(double) == 8, swap the order of 8 bytes
char: [1]->[1] // sizeof(char) == 1, swap 1 byte (no swapping needed)
並非一次完成整個結構。
不幸的是,它並沒有像反轉文件中的數據塊或文件本身那樣簡單。 您需要確切地知道要存儲什么數據類型,並反轉其中的字節。
inet.h
中的函數正是用於此目的,因此,我建議您使用它們。
因此,這使我們進入了c字符串。 如果要將c字符串存儲在文件中,是否需要交換它們的字節序? 嗯,ac字符串是一個1字節char
s的序列。 您不需要交換1個字節的char
,因此您不需要交換ac字符串中的數據!
如果您確實想交換6個字節,則可以使用std::reverse
函數:
char in[6] = get6bytes();
cout << in << endl; // shows abcdef
std::reverse(in, in+6);
cout << in << endl; // shows fedcba
如果您要進行任何大規模(大量類型)的操作,那么您可能要考慮編寫一個代碼生成器來生成這些字節交換功能(和文件讀取功能),只要您願意,它就不會太難可以找到一種工具來解析c中的結構(為此我使用了gcc-xml ,也許clang會有所幫助)。
這使得序列化成為一個更困難的問題。 如果力所能及,您可能要考慮使用XML或Google的協議緩沖區為您解決這些問題。
好的,發表您的評論后,我了解您的要求。 因此,您需要更改6字節寬的字段的字節序。
我認為這篇文章以及關於SO的問題都應該為您提供幫助,它展示了如何以不同的方式實現轉換,最快的是按位實現。 它沒有顯示六字節寬字段的實現,但是可以輕松地做出類似的解決方案。
我建議以64位整數復制您的length字段,然后實現自定義函數以交換相關的6個字節。 在任何情況下都擺脫掉或所有char指針...;)
如果您使用VC ++進行編譯,則具有以下功能: _byteswap_uint64 。 在此uint64的高端中超過6個字節,調用此函數並執行Hopla,就完成了。
在凌晨4:12進行編輯 (我一定非常沉迷於stackoverflow)
#include <iostream>
#include <stdlib.h>
typedef unsigned char byte;
typedef unsigned __int64 uint64_t; // uncomment if you are not on VC++
// in case you are not compiling with VC++ use this custom function
// It can swap data of any size. Adapted from:
// https://stackoverflow.com/questions/2182002/convert-big-endian-to-little-endian-in-c-without-using-provided-func/2182581#2182581
// see: http://en.wikipedia.org/wiki/XOR_swap_algorithm
void
swapBytes( void* v, size_t n )
{
byte* in = (byte*) v;
for( size_t lo=0, hi=n-1; hi>lo; ++lo, --hi )
in[lo] ^= in[hi]
, in[hi] ^= in[lo]
, in[lo] ^= in[hi] ;
}
#define SWAP(x) swapBytes( &x, sizeof(x) );
int
main()
{
// pointer to location of length field.
// You will have to read it from file to memory.
byte length[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
// ok, you have read it from file, now get it in an uint64_t
uint64_t i = *( (uint64_t*) length );
i <<= 16; // zero two bytes and move everything to the high end.
std::cout << std::hex << i << std::endl;
std::cout << std::hex << _byteswap_uint64( i ) << std::endl;
// generic swapping function
SWAP( i )
std::cout << std::hex << i << std::endl;
std::cin.get();
return 0;
}
// Outputs:
// 605040302010000
// 10203040506
// 10203040506
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.