Missing first line when reading in .csv file

D

Dackle

I'm having a recurring problem reading in .csv files. The first line
in the file is always missing, and so when the code below executes,
$dt[0] will contain the second line, $dt[1] the third, and so on.
Usually I get around this by manually opening the .csv file in notepad
and inserting "DUMMY" and a carriage return, then resaving. Then when
the code executes, DUMMY is skipped, and $dt[0] containes the first
line, $dt[1] the second etc., which is how I want it. In general, this
manual process works fine, but I'd rather skip it if possible. Has
anyone encountered this problem before or knows why it is happening?

open SCORES, "C:/$filename.csv" or die "can't open file: $!";
while (<SCORES>) {
chomp;
@x=<SCORES>;
}
$n=@x+0; # Number of games
for $a (0..$n) {
@c=split(",",@x[$a]);
$dt[$a]=$c[0]; # Date
$vis[$a]=$c[3]; # Visitor
$hom[$a]=$c[6]; # Home
}
 
J

Jürgen Exner

Dackle said:
I'm having a recurring problem reading in .csv files.

Indeed.
Why don't you just use Text::CSV or Text::CSV::Simple rather then rolling
you own code?

jue
 
I

ioneabu

Dackle said:
I'm having a recurring problem reading in .csv files. The first line
in the file is always missing, and so when the code below executes,
$dt[0] will contain the second line, $dt[1] the third, and so on.
Usually I get around this by manually opening the .csv file in notepad
and inserting "DUMMY" and a carriage return, then resaving. Then when
the code executes, DUMMY is skipped, and $dt[0] containes the first
line, $dt[1] the second etc., which is how I want it. In general, this
manual process works fine, but I'd rather skip it if possible. Has
anyone encountered this problem before or knows why it is happening?

open SCORES, "C:/$filename.csv" or die "can't open file: $!";
while (<SCORES>) {
chomp;
@x=<SCORES>;
}

hmm.. seems obvious enough...

the first line you have already moved the file pointer down one line.
It's as if you said: while ($_ = <SCORES>) { chomp $_ ...
now you are starting at the second line and then...
@x=<SCORES>; in scalar context, you have just sucked in the whole file
into @x starting at the second line. All you had to do was:

@x=<SCORES;

without the while.
$n=@x+0; # Number of games
for $a (0..$n) {
@c=split(",",@x[$a]);
$dt[$a]=$c[0]; # Date
$vis[$a]=$c[3]; # Visitor
$hom[$a]=$c[6]; # Home
}
 
D

Dackle

without the while.


Thanks a lot, it works now. That's been bugging me for a long time.
 
T

Tad McClellan

Dackle said:
I'm having a recurring problem reading in .csv files. The first line
in the file is always missing,


No it isn't.

Your code reads the first line and discards it without processing it.

while (<SCORES>) {


That reads the 1st line into the $_ variable.

Your code never does anything with what is in the $_ variable.
chomp;
@x=<SCORES>;


This grabs ALL of the remaining lines, so the while() loop
will *always* execute exactly one time, it is an UNloop!


$n=@x+0; # Number of games


One-character variable names really suck, have you been
programming for long?

for $a (0..$n) {
@c=split(",",@x[$a]);


You should always enable warnings when developing Perl code!

A pattern match should *look like* a pattern match.

Whitespace is not a scarce resource, feel free to use as much
of it as you like to make your code easier to read and maintain.


@c = split(/,/, $x[$a]);
 
A

Anno Siegel

I'm having a recurring problem reading in .csv files. The first line
in the file is always missing, and so when the code below executes,
$dt[0] will contain the second line, $dt[1] the third, and so on.
Usually I get around this by manually opening the .csv file in notepad
and inserting "DUMMY" and a carriage return, then resaving. Then when
the code executes, DUMMY is skipped, and $dt[0] containes the first
line, $dt[1] the second etc., which is how I want it. In general, this
manual process works fine, but I'd rather skip it if possible. Has
anyone encountered this problem before or knows why it is happening?

open SCORES, "C:/$filename.csv" or die "can't open file: $!";
while (<SCORES>) {
chomp;
@x=<SCORES>;
}

hmm.. seems obvious enough...

the first line you have already moved the file pointer down one line.
It's as if you said: while ($_ = <SCORES>) { chomp $_ ...
now you are starting at the second line and then...
@x=<SCORES>; in scalar context, you have just sucked in the whole file
into @x starting at the second line. All you had to do was:

@x=<SCORES;

without the while.
$n=@x+0; # Number of games
for $a (0..$n) {
@c=split(",",@x[$a]);
$dt[$a]=$c[0]; # Date
$vis[$a]=$c[3]; # Visitor
$hom[$a]=$c[6]; # Home
}

That fixes the particular misbehavior, but the program is still
unnecessarily roundabout.

Why read a file into an array, and then pass through it line by line
anyway? It doesn't make sense. The standard way in Perl to process
the lines of a file is a while loop (untested):

my $a = 0;
while ( <SCORES> ) {
chomp; # you forgot that, could bite some day
( $dt[ $a], $vis[ $a], $hom[ $a]) = ( split /,/)[ 0, 3, 6];
$a ++;
}

The index variable $a isn't really necessary, it is the length of the
arrays @dt etc. Here is one way to build them directly:

( $dt[ @dt], $vis[ @vis], $hom[ @hom]) = ( split /,/)[ 0, 3, 6] for
map { chomp; $_ } <DATA>;

Then again, as has been noted, this is really a job for one of the
csv modules.

Anno
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top