tags:

views:

640

answers:

2

I have a struct wich contains:

struct mystruct{
  int                id[10];
  char               text[40];
  unsigned short int len;
};

And I'm trying to unpack it in a single line, something like this:

  my(@ids,$text,$length) = unpack("N10C40n",$buff) ;

But everything is going to the first array(@ids), i've tried templates as "N10 C40 n" and "(N10)(C40)(n)" So, either this can't be done or I'm not using the proper template string.

Note: I'm using big endian data.

Any hints?

+7  A: 

In list assignment the first array or hash will eat everything (how would it know where to stop?). Try this instead:

my @unpacked        = unpack "N10Z40n", $buff;
my @ids             = @unpacked[0 .. 9];
my ($text, $length) = @unpacked[10, 11];

you could also say

my @ids;
(@ids[0 .. 9], my ($text, $length)) = unpack "N10Z40n", $buff;
Chas. Owens
With that I'm not receiving C40 to $text, instead I'm geting first C to $text and second C to $length
Arkaitz Jimenez
Hmm, I had assumed your unpack was correct, let me take a quick look.
Chas. Owens
You probably want `A40` instead of `C40`. `A40` is a space padded string of forty characters, `C40` is forty individual octets. You may also want `Z40` which would be better in keeping with the idea that `text` is a C style string (i.e. a null terminate sequence of characters).
Chas. Owens
Thanks @Chas.Owens, that did the trick
Arkaitz Jimenez
Could you update your correct answer with: my (@ids,$text,$length); (@ids[0 .. 9], $text, $length) = unpack ("N10Z40n", $buff);
Arkaitz Jimenez
+1  A: 

If the order of the @ids does not matter:

my ($length, $text, @ids) = reverse unpack("N10C40n",$buff) ;
Sinan Ünür
Interesting idea, I had not considered that.
Chas. Owens
@Chas. It is likely to be inferior to your solution in terms of speed and but for small enough lists returned by `unpack`, it might be more straightforward.
Sinan Ünür