c语言 unpack函数,Pack/Unpack 总结

大部分语言能够直接操作内存,比如C语言,能够通过内存的地址和大小,任意的修改值,在Perl,你不能任意的操作内存,但pack/unpack函数,其给你提供了一个好的选择.

pack TEMPLATE,LIST

把LIST里面的值看成是TEMPLATE指定的格式,然后转换为字节序(即内存保存的形式).

unpack TEMPLATE,EXPR

把EXPR转换为TEMPLATE指定的格式.

通过pack转换后的值将模拟一块内存,保存转换后的字节序;而unoack通过TEMPLATE指定的格式分块取出字节序,转换为指定的格式.

TEMPLATE大致分为两种.整数型和字符型.在处理时有一些差别.

整数格式

Format Description

c,C A signed/unsigned char (8-bit integer)

value

s,S A signed/unsigned short, always 16 bits

l,L A signed/unsigned long, always 32 bits

q,Q A signed/unsigned quad (64-bit integer)

value

i,I A signed/unsigned integer, native

format

n,N A 16/32 bit value in

"network" (big-endian) order

v,V A 16/32 bit value in "VAX"

(little-endian) order

U A Unicode character number. Encodes to a

character in character mode and UTF-8 (or UTF-EBCDIC in EBCDIC platforms) in

byte mode.

因为整数型规定了字节长度,所以后面接的数字表示需要格式化列表中的几个元素.*表示全部.

$foo = pack("s2",1,2);

"\1\0\2\0" on little-endian

"\0\1\0\2" on big-endian

字符格式

Format Description

a,A A null/space padded string

b,B A bit (binary) string in

ascending/descending bit order

h,H A hexadecimal string, low/high nybble

first

Z A null terminated string

因为字符型没有规定字符长度,所以后面接的数字表示每个元素接收的字符数,只是对一个元素而言.

ord(pack('b8','00100110')) produces 100 (4

+ 32 + 64)

ord(pack('B8','00100110')) produces 38 (32

+ 4 + 2)

pack('h4','1234') produces 0x21,0x43

pack('H4','1234') produces 0x12,0x34

pack('a8',"hello") produces

"hello\0\0\0"

pack('Z8',"hello") produces

"hello\0\0\0"

pack('A8',"hello") produces "hello"

unpack('a8',"hello\0\0\0")

produces "hello\0\0\0"

unpack('Z8',"hello\0\0\0")

produces "hello"

unpack('A8',"hello") produces "hello"

unpack('A8',"hello\0\0\0")

produces "hello"

特殊格式

x A

null byte.

X Back

up a byte.

@ Null fill or truncate to absolute position,

counted from the start of the innermost ()-group.

. Null

fill or truncate to absolute position specified by value.

( Start of a ()-group.

/

Unicode

pack和unpack有2种模式:字符模式(C0)

,UTF8模式(U0)

默认为C0模式,如果格式开始为U,则为U0模式.

我的理解.转换出的格式,U0的utf8 flag为on,而C0的utf-8 flag为off.

printencode( "cp936", pack( "U", 0x53cd ) )

printencode( "cp936", decode("utf-8", pack( "C0U",

0x53cd ) ) )

上面的例子都打印汉字”反”.

U默认为U0模式,直接转换为String,而C0模式转换为了Octets,所以需要decode函数转换为String.

附:

字符串与数字的转换

十进制的数字可以在数字和字符串之间自动转换.带0前缀的十六进制和八进制字符串不能自动转换为相应的数字.必须通过函数来转换.数字转换为字符串将先把数字转换为十进制,然后把十进制数字转换为字符.

hex把字符串看成十六进制并返回相应的十进制数字

可省略0x前缀,参数为字符串

oct把字符串看成相应前缀的进制转换为十进制数字.

默认为八进制,可省略0前缀,可选 0x,0b参数为字符串

chr返回数字所代表的字符.

参数为数字

ord返回字符串第一个字符的数字形式

参数为字符串

hex “0x10”hex 0x10区别

因为hex把参数看成字符串, 0x10为16,然后把16看成十六进制字符串转换为十进制数字22.

chr(“0x48”)和chr(0x48)区别

因为chr把参数看成数字,所以”0x48”转换为数字为0,所以chr(“0x48”) ==chr(0);

对于后面接字符串参数的函数(hex,oct,ord),如果参数为数字,先转换为十进制数字,然后在把数字转换为字符串,最后才传递给函数来处理.

对于后面接数字参数的函数(chr),如果参数为字符串,就要转换为十进制数字,然后在传递给函数处理.

比较零乱,慢慢整理修改了

参考 perlpacktut,perldoc pack hex oct chr ord

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值