3

这个问题就解决了。非常感谢各位^^

我的问题和我正在使用的解决方案如下所述。

原问题:--- 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";
4

4 回答 4

2

Perl 没有用于有符号大端整数的单字符格式。为此使用pack 'i>'。(这至少需要 Perl 5.10。)

于 2013-05-07T15:43:53.680 回答
2

你说你的数据是大端的,但是你i在 unpack 调用中使用了模板(一个有符号的整数值)。您应该使用N(一个无符号的 32 位大端数)。您可能需要阅读文档

于 2013-05-07T15:41:30.623 回答
1

您必须将其打包并以相反的方式解包:

print "ok\n" if 0x12653489 == unpack 'L', pack 'N', 0x89346512;
于 2013-05-08T01:51:27.257 回答
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

于 2019-01-02T05:23:19.750 回答