Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Why do i get an extra (duplicate) array element?-

by rickman1 (Novice)
on Jun 23, 2016 at 18:02 UTC ( #1166397=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to populate an array with dollar amounts from a text file via a while loop. I read them in line by line using substr. When I print out the array contents the last amount is displayed twice:

my $row; my $val; while ($row = <IN>) { $val = substr($row,0,1); @tranAmount = substr($row,68,17); foreach (@tranAmount) { print "$_\n"; } }

Output:
10.000
10.000
10.000
-30.000
-30.000 <--why is this happening? there are only 4 values within text file(10, 10, 10 and -30)

My goal is to somehow stuff all neg values within one array and pos values within another, so i can then do math with them, but i am running into this from the get-go, one hurdle at a time i guess. Thank you.

Replies are listed 'Best First'.
Re: Why do i get an extra (duplicate) array element?-
by graff (Chancellor) on Jun 23, 2016 at 18:41 UTC
    Based on the last thing you said:

    My goal is to somehow stuff all neg values within one array and pos values within another...

    I would think you want something like this:

    my @pos_array; my @neg_array; while ( my $row = <IN> ) { if ( /(-\d[.\d]+)/ ) { push @neg_array, $1; } elsif ( /(\d[.\d]+)/ ) { push @pos_array $1; } } # now do stuff with those two arrays...
    (There are better regex patterns for matching numeric strings, but the above works in the vast majority of cases.)

    As for why your script is doing what it does, well, it's hard to say without seeing the actual input data. How about you post your code with data, like this, so we can see what's happening:

    #!/usr/bin/perl use strict; use warnings; while ( my $row = <DATA>) { print $row; } __DATA__ 10.00 10.00 -30.00
    (Of course, your code and/or data will probably look different -- this is just a demonstration of the idea.)

    One last point: substr() returns a scalar, not an array; your code is creating an array with a single element on each loop iteration, and that single element is a string of (up to) 17 characters long. The code doesn't make much sense, actually.

      Why not just use the numeric value in the string:

      $ perl -demo DB<1> $A = "123" DB<2> if ( $A < 0 ) { print 'negative' }else {print 'non-negative'} non-negative DB<3> $A = "-123" DB<4> if ( $A < 0 ) { print 'negative' }else {print 'non-negative'} negative

      As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: Why do i get an extra (duplicate) array element?-
by BillKSmith (Prior) on Jun 23, 2016 at 19:35 UTC
    Pleas post a complete program (and data) that demonstrates your problem. I cannot duplicate it.
    use strict; use warnings; *IN = *DATA; my $row; my $val; while ( $row = <IN> ) { $val = substr( $row, 0, 1 ); my @tranAmount = substr( $row, 68, 17 ); foreach (@tranAmount) { print "$_\n"; } } __DATA__ 0 10 +.00000000000000 0 10 +.00000000000000 0 10 +.00000000000000 - -3 +0.0000000000000

    OUTPUT:

    10.00000000000000 10.00000000000000 10.00000000000000 -30.0000000000000

    UPDATE: Corrected formatting tag

    Bill
Re: Why do i get an extra (duplicate) array element?-
by AnomalousMonk (Bishop) on Jun 23, 2016 at 18:34 UTC

    We need to see runnable code that is equivalent to the code you're running. The code you've posted cannot ever yield an array with more than a single element:

    c:\@Work\Perl\monks>perl -wMstrict -le "my @list = qw(one two three four); ;; my @ra; for my $item (@list) { @ra = $item; printf 'print all in @ra: '; printf qq{$_ } for @ra; print 'done'; } " print all in @ra: one done print all in @ra: two done print all in @ra: three done print all in @ra: four done

    Update: E.g., something using push would do the trick:

    c:\@Work\Perl\monks>perl -wMstrict -le "my @list = qw(one two three four); ;; my @ra; for my $item (@list) { push @ra, $item; printf 'print all in @ra: '; printf qq{$_ } for @ra; print 'done'; } " print all in @ra: one done print all in @ra: one two done print all in @ra: one two three done print all in @ra: one two three four done


    Give a man a fish:  <%-{-{-{-<

      Thanks for your reply. Actually that is actual code and output. The only thing missing is where i snatch the file name from command line.

      open IN, "<$ARGV[0]" or die "Could not open input file '$ARGV[0]' $!";

      So i was reading into the push function but cannot seem to get it right. Not sure just where to place it. When i am loading the array via the substr function or printing it out?

Re: Why do i get an extra (duplicate) array element?-
by perlfan (Vicar) on Jun 23, 2016 at 18:38 UTC
    Post tested input and how you're getting handle <IN>. And if you are not:
    use strict; use warnings;

      From command-line argument. It's a fixed text file, in this case it only contains 4 lines but it can be thousands. The amount is always on that position on every line. The only way i could think of snatching them was through substr.

      open IN, "<$ARGV[0]" or die "Could not open input file '$ARGV[0]' $!";

      Flat text file would be many lines of equal length with the amounts at that same position in every line.

        If you could show us an actual data line(s), then most likely other techniques than substr() could be used. Split with an array slice is often a good approach. Just post your 4 lines within <code>...</code> blocks and we can tell exactly what is going on.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1166397]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2021-05-14 17:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (150 votes). Check out past polls.

    Notices?