我有一個「消息」的二進制文件,我試圖使用結構適合正確的變量內的字節。在我的例子中,我使用了兩種類型的消息:Tmessage和Amessage。如何擺脫結構的數據成員之間的填充字節
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <iomanip>
using namespace std;
struct Tmessage
{
unsigned short int Length;
char MessageType;
unsigned int Second;
};
struct Amessage
{
unsigned short int Length;
char MessageType;
unsigned int Timestamp;
unsigned long long int OrderReferenceNumber;
char BuySellIndicator;
unsigned int Shares;
char Stock[6];
unsigned int Price;
};
int main(int argc, char* argv[])
{
const char* filename = argv[1];
fstream file(filename, ios::in | ios::binary);
unsigned long long int pi = 0;
if(file.is_open()){ cout << filename << " OPENED" << endl; }
else { cout << "FILE NOT OPENED" << endl; }
unsigned char* memblock;
memblock = new unsigned char[128];
file.read((char *)memblock, 128);
cout << "BINARY DATA" << endl;
while (pi < 128)
{
cout << setw(2) << hex << static_cast<unsigned int>(memblock[pi]) << " ";
pi++;
if((pi%16)==0) cout << endl;
}
unsigned int poi = 0;
Tmessage *Trecord;
Trecord = (Tmessage *)memblock;
cout << "Length: " << hex << (*Trecord).Length << endl;
cout << "Message type: " << hex << (*Trecord).MessageType << endl;
cout << "Second: " << hex << (*Trecord).Second << endl;
poi = poi + 7; cout << endl;
Amessage *Arecord;
Arecord = (Amessage *)(memblock+poi);
cout << "Length: " << hex << (*Arecord).Length << endl;
cout << "Message type: " << hex << (*Arecord).MessageType << endl;
cout << "Timestamp: " << hex << (*Arecord).Timestamp << endl;
cout << "OrderReferenceNumber: " << hex << (*Arecord).OrderReferenceNumber << endl;
cout << "BuySellIndicator: " << hex << (*Arecord).BuySellIndicator << endl;
cout << "Shares: " << hex << (*Arecord).Shares << endl;
cout << "Stock: " << hex << (*Arecord).Stock << endl;
cout << "Price: " << hex << (*Arecord).Price << endl;
delete memblock;
file.close();
cout << endl << "THE END" << endl;
return 0;
}
當我運行該程序的輸出:
stream OPENED
BINARY DATA
0 5 54 0 0 62 72 0 1c 41 0 f 42 40 0 0
0 0 0 4 2f 76 53 0 0 3 e8 53 50 59 20 20
20 0 11 5 d0 0 1c 41 0 f 42 40 0 0 0 0
0 4 2f 78 42 0 0 3 e8 53 50 59 20 20 20 0
10 f7 5c 0 1c 41 0 f 42 40 0 0 0 0 0 4
2f 90 53 0 0 1 2c 53 50 59 20 20 20 0 11 2
b0 0 5 54 0 0 62 76 0 d 44 14 25 78 80 0
0 0 0 0 4 2f 90 0 d 44 14 25 78 80 0 0
Length: 500
Message type: T
Second: 726200
Length: 1c00
Message type: A
Timestamp: 40420f
OrderReferenceNumber: 53762f0400000000
BuySellIndicator:
Shares: 20595053
Stock:
Price: 420f0041
THE END
的程序放置字節Tmessage內部結構正常。 (0 5 54 0 0 62 72)
但是,解析Amessage時發生了某些情況。
(0 1C 41 0,F 42 40 0 0 0 0 0 4 2F 76 53 0 0 3 E8 53 50 59 20 20 20 0 11 5 D0)
的Lenght,消息類型和時間戳是正確的,但OrderReferenceNumber包含「53」字節屬於BuySellIndicator,然後另一個變量是不正確的。
正確的消息輸出應該是:
長度:1C 0
消息類型:41
時間戳:40 42 f 0的
OrderReferenceNumber:76 2F 4 0 0 0 0 0
BuySellIndicator:53
股數:E8 3 0 0
庫存:53 50 59 20 20 20
價格:D0 5 11 0
的2個問題: a)爲什麼OrderReferenceNumber包含「53」字節? b)我認爲「char stock [6]」不起作用,因爲在Share的字節和Price的字節之間有超過6個字節。我如何將6個字節放入char向量或字符串?
注意:我知道我必須交換字節,因爲二進制數據以big-endian結尾。這就是爲什麼「股票」不應該交換。 非常感謝您的幫助!親切的問候,
編譯器(對齊/不對齊)指令也可能影響結構和對象的填充,因此即使對於不可移植的程序也是如此,否則它可能會因不明顯的原因而表現不同。 – 2010-07-19 01:24:35