$lineNumber +=1 does not increment

W

William

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?
 
A

A. Sinan Unur

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
 
D

Dominique Crétel

$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 :
 
G

Glenn Jackman

At 2006-01-30 09:54AM said:
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++;
}
 
P

Paul Lalli

William said:
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 = said:
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
 
W

William

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
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.
 
P

Paul Lalli

William said:
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*


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
 
W

William

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.
 
J

Joe Smith

William said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top