dpenny has asked for the wisdom of the Perl Monks concerning the following question:

Am on a Win2K box, and don't understand the following output & snippet. Can someone plse explain and tell me how to get integers from my string, I am expecting a single integer result to be 114,200 (w/o the comma of course).
string to unpack >0114200<
fmt=A7 >> pr=0114200
fmt=I7 >> pr=875639088
fmt=i7 >> pr=875639088
fmt=L7 >> pr=875639088
fmt=l7 >> pr=875639088

use strict;
use warnings;
my $data='0114200';
print "string to unpack >$data<\n";
my $fmt = 'A7';
my $pr = unpack($fmt,$data);
print "fmt=$fmt >> pr=$pr\n";
$fmt = 'I7';
$pr = unpack($fmt,$data);
print "fmt=$fmt >> pr=$pr\n";
$fmt = 'i7';
$pr = unpack($fmt,$data);
print "fmt=$fmt >> pr=$pr\n";
$fmt = 'L7';
$pr = unpack($fmt,$data);
print "fmt=$fmt >> pr=$pr\n";
$fmt = 'l7';
$pr = unpack($fmt,$data);
print "fmt=$fmt >> pr=$pr\n";

Thanks.
--
Dick Penny

Replies are listed 'Best First'.
Re: UNPACK help plse
by graff (Chancellor) on Sep 05, 2002 at 06:27 UTC
    The last time I checked, nothing needs to be done to a scalar variable containing a string of digit characters in order for it to be treated as an integer. The fact that it is made up of digits means that it will be interpreted as a numeric value in any sort of numeric context -- while still being used as a string in any string context. Run this snippet and see what you get:
    $data = '01142000'; print "$data + 1 = ", $data + 1, $/; print "$data / 2 = ", $data / 2, $/; print "sqrt($data) = ", sqrt( $data ), $/;
    The cases where you really need unpack (and pack) tend to be hard to explain... and builtins like "ord()", "chr()", "hex()" and so on tend to provide the most common functions that (un)pack might be used for -- and in much clearer terms.

    BTW, I think the integer formats you were trying (I7,i7, L7,l7) are supposed to tell unpack that the scalar data being passed to it should contain seven binary "int" (i/I) or "long int" (l/L) values -- these would be either 16- and 32-bit values or 32- and 64-bit values (or 32- and 32-bit values), depending on your system (and maybe depending on how your perl interpreter was compiled for your system). So, it would have tried to read 7*2=14 bytes (16-bit i/I) or 7*4=28 bytes (32-bit i/I or l/L) or 7*8=56 bytes (64-bit l/L) from $data. But you only fed it a scalar containing 8 bytes. Whatever it ended up doing, at least it did the same thing consistently for these cases.

    To top it off, of course, the perldoc descriptions for of pack and unpack are undeniable the hardest to grasp. Don't feel bad if you don't grok it, even after working through your own experiments with it.

    (update: fixed a couple typos)

Re: UNPACK help plse
by fglock (Vicar) on Sep 04, 2002 at 20:14 UTC

    just add zero to make it look like an integer

    $var + 0

Re: UNPACK help plse
by Zaxo (Archbishop) on Sep 05, 2002 at 07:24 UTC

    Your data string is:

            chr    '0' '1' '1' '4' '2' '0' '0'
            ord    48  49  49  52  50  48  48
        intel word lo  lh  hl  hi  lo  lh  hl  ??
    
    Now the A7 template unpacks this string as its ascii characters, just as it was constructed. On the ia-32 architecture native int and native long are both customarily 4 bytes, so you expect i,l to give the same results, as well as I,L, the unsigned variants. If the number is less than 2**31, unsigned, both signed and unsigned give the same results.

    Now unpack's repeat count templates give up if the data string is too short to provide all the fields. '0114200' only has enough data for one native int, so that's all you get:

    perl -e'print 52*2**24 + 49*2**16 + 49*2**8 + 48,$/;" 875639088

    After Compline,
    Zaxo

Re: UNPACK help plse
by greenFox (Vicar) on Sep 05, 2002 at 01:11 UTC

    int is probably what you are after...

    I recommend that you open up the perlfunc man page (man perlfunc or perldoc perlfunc on your system) and get familiar with all of the built-ins.

    Update:graff is of course right a scalar consisting of only digits is already an int or can be... /me wanders off to re-read perldata :)

    --
    Until you've lost your reputation, you never realize what a burden it was or what freedom really is. -Margaret Mitchell