$lineNumber +=1 does not increment

Discussion in 'Perl Misc' started by William, Jan 30, 2006.

  1. William

    William Guest

    I am trying to parse a file with the following code:

    #!/usr/bin/perl -w

    use strict;

    # reads in all lines from diff.txt
    open ( FD, "diff.txt" ) || die ( "Cannot open file diff.txt" );
    my @fileContent = <FD>;
    close ( FD );

    my $lineNumber = 1; # file starts with line 1
    my $C_previousPortfolio;
    my $D_newPortfolio;

    foreach my $line ( @fileContent ) {
    print "$C_previousPortfolio, $D_newPortfolio, $lineNumber";
    # skip line if line number is odd
    if ( 1 == ($lineNumber % 2) ) {
    next;
    }
    else {
    if ( $line =~ m/\>/ ) {
    ( $C_previousPortfolio, $D_newPortfolio ) = split ( /\>/,
    $line );
    }
    }
    $lineNumber += 1;
    }

    File content:
    0a1
    > "2nd D difference"

    3a5
    > "IN 27 but not in 26 - D"


    Current output:
    Use of uninitialized value at ./read_differences.pl line 15.
    Use of uninitialized value at ./read_differences.pl line 15.
    , , 1
    Use of uninitialized value at ./read_differences.pl line 15.
    Use of uninitialized value at ./read_differences.pl line 15.
    , , 1
    Use of uninitialized value at ./read_differences.pl line 15.
    Use of uninitialized value at ./read_differences.pl line 15.
    , , 1
    Use of uninitialized value at ./read_differences.pl line 15.
    Use of uninitialized value at ./read_differences.pl line 15.
    , , 1

    Expected output:
    , , 1
    , 2nd D difference, 2
    , , 3
    , IN 27 but not in 26 - D, 4


    Questions:
    1) Why doesn't $lineNumber increment?
     
    William, Jan 30, 2006
    #1
    1. Advertising

  2. William <> wrote in
    news:p:

    > I am trying to parse a file with the following code:
    >
    > #!/usr/bin/perl -w
    >
    > use strict;
    >
    > # reads in all lines from diff.txt
    > open ( FD, "diff.txt" ) || die ( "Cannot open file diff.txt" );
    > my @fileContent = <FD>;
    > close ( FD );


    Please see the posting guidelines for this group to learn how to provide
    the data your script needs to work.


    > my $lineNumber = 1; # file starts with line 1
    > my $C_previousPortfolio;
    > my $D_newPortfolio;
    >
    > foreach my $line ( @fileContent ) {
    > print "$C_previousPortfolio, $D_newPortfolio, $lineNumber";
    > # skip line if line number is odd
    > if ( 1 == ($lineNumber % 2) ) {
    > next;
    > }
    > else {
    > if ( $line =~ m/\>/ ) {
    > ( $C_previousPortfolio, $D_newPortfolio ) = split ( /\>/,
    > $line );
    > }
    > }
    > $lineNumber += 1;
    > }



    I have no idea what this code is trying to do. I don't know what data you
    are expecting to read.

    Formatting your source better, and therefore respecting your reader pays
    dividends for you as well.

    > Questions:
    > 1) Why doesn't $lineNumber increment?


    Why should it? Stripping the parts that are not essential:

    my $lineNumber = 1;

    foreach my $line ( @fileContent ) {
    if ( 1 == ($lineNumber % 2) ) {
    next;
    }
    $lineNumber += 1;
    }

    The condition in the if statement above will be true upon entry to this
    loop, and therefore it will never get to the statement where $lineNumber is
    incremented.

    Sinan
     
    A. Sinan Unur, Jan 30, 2006
    #2
    1. Advertising

  3. $lineNumber start with value 1
    In your foreach, you do a 'next' if ($lineNumber % 2) == 1
    It's the case, so you jump in the next loop without increasing it's value !

    William a écrit :
    > my $lineNumber = 1; # file starts with line 1
    >
    > foreach my $line ( @fileContent ) {
    > print "$C_previousPortfolio, $D_newPortfolio, $lineNumber";
    > # skip line if line number is odd
    > if ( 1 == ($lineNumber % 2) ) {
    > next;
    > }
    > else {
    > if ( $line =~ m/\>/ ) {
    > ( $C_previousPortfolio, $D_newPortfolio ) = split ( /\>/,
    > $line );
    > }
    > }
    > $lineNumber += 1;
     
    Dominique Crétel, Jan 30, 2006
    #3
  4. At 2006-01-30 09:54AM, William <> wrote:
    > I am trying to parse a file with the following code:
    >

    [...]
    > my $lineNumber = 1; # file starts with line 1
    > my $C_previousPortfolio;
    > my $D_newPortfolio;
    >
    > foreach my $line ( @fileContent ) {
    > print "$C_previousPortfolio, $D_newPortfolio, $lineNumber";
    > # skip line if line number is odd
    > if ( 1 == ($lineNumber % 2) ) {
    > next;
    > }


    Logic error. Since $lineNumber starts as 1, this if expression always
    evaluates true, and you call 'next' in every iteration of the loop. You
    will never reach your increment statement.

    > else {
    > if ( $line =~ m/\>/ ) {
    > ( $C_previousPortfolio, $D_newPortfolio ) = split ( /\>/,
    > $line );
    > }
    > }
    > $lineNumber += 1;
    > }

    [...]
    > Questions:
    > 1) Why doesn't $lineNumber increment?


    To fix, put the increment statement in a continue block so it is invoked
    for each iteration of the loop even if you call 'next':

    my $lineNumber = 1;
    foreach my $line (...) {
    if (1 == $lineNumber%2) {
    next;
    }
    ...
    }
    continue {
    $lineNumber++;
    }

    --
    Glenn Jackman
    Ulterior Designer
     
    Glenn Jackman, Jan 30, 2006
    #4
  5. William

    Paul Lalli Guest

    William wrote:
    > I am trying to parse a file with the following code:
    >
    > #!/usr/bin/perl -w
    >
    > use strict;


    Very, very good! However, it is these days considered better to type
    use warnings;
    rather than the -w


    > # reads in all lines from diff.txt
    > open ( FD, "diff.txt" ) || die ( "Cannot open file diff.txt" );


    It's far better to use the three-argument form of open(), to use
    lexical filehandles instead of global barewords, and to include the
    *reason* the open failed. (And also, IMHO, to eliminate the needless
    punctuation....)

    open my $FD, '<', 'diff.txt' or die "Cannot open file diff.txt: $!"


    > my @fileContent = <FD>;
    > close ( FD );


    Why are you reading the entire file into memory at once? Why not
    process one line at a time?

    > my $lineNumber = 1; # file starts with line 1


    If you process the file one line at a time, Perl keeps track of this
    value for you, in the $. variable.

    > my $C_previousPortfolio;
    > my $D_newPortfolio;
    >
    > foreach my $line ( @fileContent ) {


    while (my $line = <$FD>) {

    > print "$C_previousPortfolio, $D_newPortfolio, $lineNumber";
    > # skip line if line number is odd
    > if ( 1 == ($lineNumber % 2) ) {
    > next;


    Here, you have a problem. You've skipped and gone on to the next
    iteration of your foreach loop, but you never incremented $lineNumber.
    That is your bug.

    > }
    > else {
    > if ( $line =~ m/\>/ ) {
    > ( $C_previousPortfolio, $D_newPortfolio ) = split ( /\>/,
    > $line );
    > }
    > }
    > $lineNumber += 1;


    If you want this statement to be executed each iteration of the loop,
    regardless of any next; statements, put it in a continue{} block at the
    end of the loop...

    > }


    continue {
    $lineNumber ++;
    }

    Re-writing your entire loop:

    while (my $line = <$FD>) {
    print "$C_previousPortfolio, $D_newPortfolio, $.\n"
    next if 1 == $. % 2;
    if ($line =~ /(.*)>(.*)/) {
    ($C_previousPortfolio, $D_newPortfolio) = ($1, $2);
    }
    }


    Hope this helps
    Paul Lalli
     
    Paul Lalli, Jan 30, 2006
    #5
  6. William

    William Guest

    On Mon, 30 Jan 2006, Paul Lalli wrote:

    >
    > William wrote:
    >> I am trying to parse a file with the following code:
    >>
    >> #!/usr/bin/perl -w
    >>
    >> use strict;

    >
    > Very, very good! However, it is these days considered better to type
    > use warnings;
    > rather than the -w


    I got an error when I tried use warnings. We had an old version of perl:
    perl -v

    This is perl, version 5.005_03 built for sun4-solaris

    >
    >
    >> # reads in all lines from diff.txt
    >> open ( FD, "diff.txt" ) || die ( "Cannot open file diff.txt" );

    >
    > It's far better to use the three-argument form of open(), to use
    > lexical filehandles instead of global barewords, and to include the
    > *reason* the open failed. (And also, IMHO, to eliminate the needless
    > punctuation....)
    >
    > open my $FD, '<', 'diff.txt' or die "Cannot open file diff.txt: $!"


    I got the following error:
    Too many arguments for open at ./read_differences.pl line 11, near
    ""/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";"
    Execution of ./read_differences.pl aborted due to compilation errors.


    If I try:

    open my $NEW_FD, "/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";

    Can't use an undefined value as a symbol reference at
    ../read_differences.pl line 11.

    Please advice.
     
    William, Jan 30, 2006
    #6
  7. William

    Paul Lalli Guest

    William wrote:
    > On Mon, 30 Jan 2006, Paul Lalli wrote:
    > > use warnings;
    > > rather than the -w

    >
    > I got an error when I tried use warnings. We had an old version of perl:
    > perl -v
    >
    > This is perl, version 5.005_03 built for sun4-solaris


    *shudder*

    > > open my $FD, '<', 'diff.txt' or die "Cannot open file diff.txt: $!"

    >
    > I got the following error:
    > Too many arguments for open at ./read_differences.pl line 11, near
    > ""/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";"
    > Execution of ./read_differences.pl aborted due to compilation errors.
    >
    >
    > If I try:
    >
    > open my $NEW_FD, "/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";
    >
    > Can't use an undefined value as a symbol reference at
    > ./read_differences.pl line 11.
    >
    > Please advice.


    As you stated, you have an old version of Perl. My recommendations
    were based on the assumption that you were using a Perl from this
    decade.

    I strongly advise you to upgrade.

    Paul Lalli
     
    Paul Lalli, Jan 30, 2006
    #7
  8. William

    William Guest

    On Mon, 30 Jan 2006, Paul Lalli wrote:

    > William wrote:
    >> On Mon, 30 Jan 2006, Paul Lalli wrote:
    >>> use warnings;
    >>> rather than the -w

    >>
    >> I got an error when I tried use warnings. We had an old version of perl:
    >> perl -v
    >>
    >> This is perl, version 5.005_03 built for sun4-solaris

    >
    > *shudder*
    >
    >>> open my $FD, '<', 'diff.txt' or die "Cannot open file diff.txt: $!"

    >>
    >> I got the following error:
    >> Too many arguments for open at ./read_differences.pl line 11, near
    >> ""/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";"
    >> Execution of ./read_differences.pl aborted due to compilation errors.
    >>
    >>
    >> If I try:
    >>
    >> open my $NEW_FD, "/app_rre/home/mx_rre/scripts/Scenario/reports/rskpolicy/new_tmp.txt";
    >>
    >> Can't use an undefined value as a symbol reference at
    >> ./read_differences.pl line 11.
    >>
    >> Please advice.

    >
    > As you stated, you have an old version of Perl. My recommendations
    > were based on the assumption that you were using a Perl from this
    > decade.
    >
    > I strongly advise you to upgrade.


    I will need to have a discussion with my management first.
    But I totally agree with you.
     
    William, Jan 30, 2006
    #8
  9. William

    Joe Smith Guest

    William wrote:

    > my $lineNumber = 1; # file starts with line 1
    > foreach my $line ( @fileContent ) {
    > if ( 1 == ($lineNumber % 2) ) {
    > next;
    > ...
    > $lineNumber += 1;
    > }


    Your program would have worked if you started at zero and
    did an unconditional pre-increment at the top of the if().

    my $lineNumber;
    foreach my $line (@fileContent) {
    if (++$lineNumber % 2) {
    print "$lineNumber is not a multiple of 2, skipping\n";
    next;
    } else {
    print "$lineNumber is even\n"
    split(...);
    }
    }

    -Joe
     
    Joe Smith, Feb 6, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christina N
    Replies:
    0
    Views:
    353
    Christina N
    Jun 21, 2004
  2. Replies:
    104
    Views:
    11,024
    Jordan Abel
    Oct 28, 2005
  3. Replies:
    99
    Views:
    2,511
    eliza81
    Jun 11, 2010
  4. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    899
    Alf P. Steinbach /Usenet
    May 22, 2011
  5. Peng Yu

    post increment or pre increment?

    Peng Yu, Nov 21, 2008, in forum: Perl Misc
    Replies:
    7
    Views:
    529
    Peter J. Holzer
    Nov 23, 2008
Loading...

Share This Page