在Python和C結構之間轉換的函數,用於二進制數據存儲和處理,處理c語言中的結構體。
常用函數
常用函數包括如下三個,pack將數據封裝成字節流;unpack根據給定格式解析字節,返回tuple類型; calcsize返回給定的格式佔用內存的字節數。
struct.pack(fmt, v1, v2, ...) -> bytes
struct.unpack(fmt, buffer) -> (v1, v2, ...)
struct.calcsize(fmt) -> int
格式符(fmt)
格式符用來表示字節封裝或解析的格式,注意:
1.每個格式符前可以有一個數字,表示個數,比如4s表示長度爲4的字符串,2i表示兩個整數;
2.q和Q只在機器支持64位操作時有意義;
3.P用來轉換一個指針,其長度和計算機相關;
4.f和d的長度和計算機相關。
格式符 | C語言類型 | Python類型 | 內存大小 |
---|---|---|---|
x | 填充字節 | 無 | 1 |
c | char | string(長度爲1) | 1 |
b | signed char | int | 1 |
B | unsigned char | int | 1 |
h | short | int | 2 |
H | unsigned short | int | 2 |
i | int | int | 4 |
I | unsigned int/long | int/long | 4 |
L | unsigned long | long | 8 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | 1 |
p | char[] | string | 1 |
? | _Bool | bool | 1 |
對齊方式
字符 | 字節順序 | 大小 |
---|---|---|
@(默認) | 與本機一致 | 湊夠4個字節 |
= | 與本機一致 | 按原字節數 |
< | 小端 | 按原字節數 |
> | 大端 | 按原字節數 |
! | network(大端) | 按原字節數 |
示例
pack
*注意:*python3所有字符串都是 unicode 字符串,若直接用pack封裝會報如下錯誤:
#error: argument for 's' must be a bytes object
因此字符串處理前需要使用’utf-8’編碼,具體方法如下代碼段。
import struct
a=10
b='apple'
c=35.9
d=True
data=struct.pack("i5sf?",a,b.encode('utf-8'),c,d)#對字符串先編碼
print(data)
#輸出:b'\n\x00\x00\x00apple\x00\x00\x00\x9a\x99\x0fB\x01'
unpack
import struct
t=struct.unpack("i5sf?",data)
#或者:t1,t2,t3,t4=struct.unpack("i5sf?",data)
print(t)
#輸出:(10, b'apple', 35.900001525878906, True)
calcsize
import struct
struct.calcsize('5s')
#輸出:5
struct.calcsize('3if')
#輸出:16
#16=3*4+4
struct.calcsize('i5sf?')
#輸出:17
#17=4+5+3+4+1
'''
注意:其中3表示填充,因爲默認對齊方式爲@
字節字符串s可以以任何偏移量開頭,因爲其標準大小爲1;
i,f等只能以4的倍數的偏移量開頭。例如0、4、8等;
L,d等只能以8的倍數的偏移量開頭。例如0、8、16等。
'''
struct.calcsize('=i5sf?')
#輸出:14
#14=4+5+4+1 按原字節數