in reply to Unpacking fixed length records

I may be still in shock at grouping in unpack (new in 5.8?), but will this work for you? (Please excuse the clumsy dumping)
  $str = "\004ABC\003DE\002F";
  $fmt = "(C X /a)*";
  @z = unpack($fmt,$str);
  foreach $z (@z) {
    print "'", join("', '", map {ord} split(//,$z)),"'\n";
  }
returns
'4', '65', '66', '67'
'3', '68', '69'
'2', '70'
So you could probably get your desired result with "(n XX /a)*" ?

--
I'm a pessimist about probabilities; I'm an optimist about possibilities.
Lewis Mumford

Replies are listed 'Best First'.
Re: Re: Unpacking fixed length records
by diotalevi (Canon) on Oct 07, 2002 at 00:15 UTC

    Ok I get it. I can do unpack '(nX/a)*' but apparently more than one 'X' isn't supported. The pattern I would actually use is '(nXX/a)*' and that doesn't parse. Boo hoo! This almost looks like a thinko on the part of whoever implemented this for 5.8.0. It's a nice feature but I don't know how many people really want to be limited to packed strings of 255 chars or less.

    __SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B:: +svref_2object(sub{})->OUTSIDE
      B Bu But it works for me? My "perl -v" insists it is 5.8.0. What version of Perl are you running? I changed the test program input and format to more closely mirror what you wanted.
        $str = "\000\005ABC\000\004DE\000\003F";
        $fmt = "(n XX /a)*";
      
      returns
      '0', '5', '65', '66', '67'
      '0', '4', '68', '69'
      '0', '3', '70'
      
      Also tried it with "(nXX/a)*" with same results. When you run the same program does it get different results or a syntax error? You said it doesn't parse? As in it doesn't split the input correctly? Could it be a big/little-endian problem?

      (shenme wants to know if the battery in his new toy has run down)

        Ok, so it appears to be the data that's goofy. I re-ran your code snippet and it worked just fine. When I run that on my data I get the error "/ must follow a numeric type" which according to diagnostics is "(F) You had an unpack template that contained a '#', but this did not follow some numeric unpack specification. See perlfunc/pack.". That's an unhelpful error (to me anyway). I had misinterpreted that to be a compile-time error so didn't even think that the unpack format was valid.

        Now I'm stuck with a blob of data that doesn't appear to unpack correctly. I tried cutting bits off from the end and oddly - it works sometimes though not consistently from different contexts. The behaviour is so bizarre that I'm just going to have to write a better test for it to tease out where either I'm going wrong or perl is buggy. When I know something further I'll post to this or a new thread later.

        __SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B:: +svref_2object(sub{})->OUTSIDE