C++與Qt的位元組序探究:

wyjun0418發表於2020-09-26

1. 位元組序:

  • 大端位元組:資料的低位儲存在記憶體的高地址中,而資料的高位儲存在記憶體的低地址;
  • 小端位元組:資料的低位儲存在記憶體的低地址中,而資料的高位儲存在記憶體的高地址中;

2. C++讀寫二進位制檔案:以小端位元組序執行

注意: 

1.可以使用inStream.fail()函式判斷是否讀取正確;

2.inStream.read()讀取時必須強轉為char*,且必須為變數地址:inStream.read((char *)&size, sizeof(int));

3. inStream >>只能按單個位元組讀取;

3.注意資料的位元組數:int(4個位元組))、unsigned short(2位元組)、float(4位元組)、double(8位元組);

5.地址變動:seek(A , ios:beg/cur/end):A是指需要跳過多少個位元組,ios:beg為從起始地址開始計算跳過A個位元組;iOS::cur是從當前位置計算往後跳A個位元組,ios::end指從該檔案的末尾地址計算跳過A個位元組;

因此,需要讀取固定地址的資料時候要格外注意;

2.Qt讀寫二進位制檔案:預設大端位元組序執行

  • 參考:Qt對大小端位元組序的處理:https://blog.csdn.net/iEearth/article/details/77009054
  • 資料讀取:QDataStream或者QTextStream進行讀寫,但你也可以使用read(),readLine(),readAll(),write()讀寫。QFile也支援getChar(),putChar(),和ungetChar();
  • Qt中對大小端轉換的函式:qToBigEndian、qFromBigEndian、qToLittleEndian(T source)、qFromLittleEndian(T source) 、qToBigEndian、qToLittleEndian;
  • Qdatastream設定資料大小端;預設為大端讀寫,可以通過設定引數轉化大小端;
  • 設定讀取的地址:檔案總大小:size()可以返回檔案的大小;當前檔案位置:pos();地址移動seek(),atend可以判斷是否讀到了檔案結尾;

3.C++大小端轉換:

1)聯合體union聯合體共用記憶體的特性,因此迴避了強制型別轉換;

typedef union FLOAT_CONV { float f; char c[4]; }float_conv; f和char c[4]共用四個位元組的記憶體地址;

即賦值的互斥性;可以有多個資料成員:但是在任意時刻,聯合中只能有一個資料成員可以有值。當給聯合中某個成員賦值之後,該聯合中的其它成員就變成未定義狀態了。

union Token{char cval;int ival;double dval;};分配的記憶體為double的記憶體(以最大位元組變數為準);

2)整形、浮點型、短整型。參考https://www.cnblogs.com/chay/p/10587384.html#_label0

3)double形我們參考float,如下:

typedef union Double_CONV
{
    float Do;
    char c[8];
}double_conv;


double BLEndianFloat(double value)
{
    float_conv d1,d2;
    d1.Do = value;
    d2.c[0] = d1.c[7];
    d2.c[1] = d1.c[6];
    d2.c[2] = d1.c[5];
    d2.c[3] = d1.c[4];
    d2.c[4] = d1.c[3];
    d2.c[5] = d1.c[2];
    d2.c[6] = d1.c[1];
    d2.c[7] = d1.c[0];
    return d2.Do;
}

4.工具:大小端轉換和二進位制檔案檢視工具:

在此非常感謝文章中引用到的各位博主的文章,對我的幫助很大;

 

 

相關文章