http://www.perlmonks.org?node_id=677526

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

I'm pretty new to Perl but for the life of me I can't figure out this problem. I'm trying to read a tab delimited text file line by line but when I try to read the file it crashes.
#!/usr/local/bin/perl use warnings; print "1\n"; open((IN),"<dev.csv"); print "2\n"; while (($read)=<IN>) { print "3\n"; chomp($read); @lst = split(/\t/,$read); print "$lst[1]"; } close(IN);
The program always prints out 1,2 but never gets to 3. I've tried using Tie::Handle::CSV but it gets the same result. Can anyone help?

Replies are listed 'Best First'.
Re: Reading a CSV file
by kyle (Abbot) on Mar 31, 2008 at 14:36 UTC

    This isn't the source of your problem, but it is something else you'll need to fix. On this line:

    while (($read)=<IN>) {

    By putting $read in parentheses, you create a list context for the <IN>. As such, it will read the whole file and just put the first line in $read.

    I think you want this instead:

    while ($read=<IN>) {
      Thanks, I was trying to do something else and forgot to remove those parentheses.
Re: Reading a CSV file
by Limbic~Region (Chancellor) on Mar 31, 2008 at 14:20 UTC
    alchang,
    Welcome. It is very likely your file is never being opened for reading but you are not checking the return code.
    use strict; use warnings; open(my $fh, '<', 'dev.csv') or die "Unable to open 'dev.csv' for read +ing: $!"; while (<$fh>) { print; }
    See what the above code does for you. Also, if you are handling CSV, I would recommend using Text::CSV which recently got a major overhaul.

    Cheers - L~R

      Thanks for your response. I copied and pasted your code but there still was no output. I'll try to obtain Text::CSV and see if that works.
        alchang ,
        If there was no output at all, then you likely have an empty file. That code should have done 1 of 2 things:
        1. Generated an error because you were unable to open the file 2. Printed every line in the file
        Since it did neither, I must assume that the file exists, you can open it, but that it is empty. Using a module will not change that. I recommended it because CSV can be tricky but you aren't yet at the tricky part.

        Update: Since you have said elsewhere in the thread that the file is 63MB - consider that you may have two files with the same name in different directories. Since you have not told perl to open a file with an absolute path, it is looking for a file in the same directory that you executed perl from.

        Cheers - L~R

Re: Reading a CSV file
by wade (Pilgrim) on Mar 31, 2008 at 14:43 UTC
    Yeah, there are a few things you might consider changing, here. Each program should start with
    use strict;
    in addition to use warnings;. Once you do that, though, you'll need the lines:
    my $read; my @lst;
    I noticed a couple minor things about your 'open'. You probably shouldn't put IN in parens and you'll be a little safer if you use the 3 parameter version. The other advice, to use 'or die' is necessary, here:
    open (IN, "<", "dev.csv") or die "couldn't open 'dev.csv': $!\n";
    After you get this working, though, you'll stumble across a subtle bug in your 'while' loop. By putting $read in parens, you've made it an element of a list. <IN> in a list context will slurp-up the whole file and, since there's only one element of the list ($read), only the first line gets assigned to something -- the rest of the file gets discarded. This way, the 'while' is guaranteed to run exactly once. Instead, you probably want:
    while (my $read=<IN>) { print "3\n"; chomp ($read); #... }
    Hope this helps!
    --
    Wade
      Thanks for the advice, I'm still pretty new to Perl as you can see :(.
Re: Reading a CSV file
by Fletch (Bishop) on Mar 31, 2008 at 14:18 UTC

    Perhaps if you checked the return value from your open call before blindly trying to read from the filehandle in question you might obtain some enlightenment . . .

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Reading a CSV file
by Tux (Canon) on Mar 31, 2008 at 14:30 UTC

    Let's start with the title. TAB separated data is not CSV, but Text::CSV_XS can do that too

    use Text::CSV_XS; my $csv = Text::CSV_XS->new ({ sep_char => "\t", binary => 1 }); open my $fh, "<", "dev.csv" or die "dev.csv: $!"; while (my $row = $csv->getline ($fh)) { print $row->[1]; }

    Enjoy, Have FUN! H.Merijn
Re: Reading a CSV file
by Narveson (Chaplain) on Mar 31, 2008 at 14:30 UTC

    What's in dev.csv? The output you report is consistent with it being an empty file.

      Here's a snippet of it, the whole file is 63 megs.
      Affy_identifier AGI code ATGE_1_A ATGE_1_B ... 244901_at orf25 5.708836453 5.941182538 ... 244902_at nad4L 6.157625809 5.994973686 ...