此问题已解决。非常感谢你们^^
我的问题和我正在使用的解决方案如下所述。
原始问题:---编辑2013-05-08
我知道我可以通过C ++完成这项任务:
struct { /* File Header */
int a;
int b;
short c;
short d;
} PPPhdr;
PPPhdr head;
fstream fst;
fst.open("file.txt", ios_base::in|ios_base::binary);
fst.read((char*)&head, sizeof(PPPhdr));
SwapInt32(&(head.a));
SwapInt32(&(head.b));
SwapShort(&(head.c));
SwapShort(&(head.d));
所以,基本上SwapInt32会这样做:
0x89346512 -> 0x12653489
SwapShort会这样做:
0x3487 -> 0x8734
现在我的问题是,我怎么能在Perl中做到这一点?
我的方式:
open FH, "<file.txt" or die print "Cannot open file\n";
binmode FH;
read FH, $temp, 12;
($a,$b) = unpack("N2", substr($temp,0,8));
($c,$d) = unpack("n2", substr($temp,8,4));
close(FH);
print "$a\n$b\n$c\n$d\n";
答案 0 :(得分:2)
您说您的数据是big-endian,但您在解包调用中使用的是i
模板(有符号整数值)。您应该使用N
(无符号32位大端数字)。您可能需要阅读documentation。
答案 1 :(得分:2)
Perl对于有符号的大端整数没有单字符格式。请使用pack 'i>'
。 (这至少需要Perl 5.10。)
答案 2 :(得分:1)
你必须打包并反过来打开包装:
print "ok\n" if 0x12653489 == unpack 'L', pack 'N', 0x89346512;
答案 3 :(得分:0)
我做到了。首先,我感觉自己是bigendian还是littleendian。要么读取文件并查看字节序标志(例如TIFF文件中的字节0-1),要么通过
来感知我自己系统的字节序 $x = pack ("S", 256);
$bigendian = ord(substr ($x, 0, 1)); # 1 for bigendian 0 for littleendian
一旦我有了$ bigendian的值,就可以使用变量进行打包和解包:
$short = $bigendian ? "n" : "v";
$long = $bigendian ? "N" : "V";
($a,$b) = unpack($long . "2", substr($temp,0,8));
($c,$d) = unpack($short . "2", substr($temp,8,4));
nN代表“网络”,该标准要求使用bigendian
vV代表“ Vax”,这是旧的DEC系统,是littleendian