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

Hi, this script does exactly what i want it to which is select the 14th and 15th column from a table and print it. but when it runs the horrible error message is " error! use of uninitialised value in concatenation (.) or string near FILEHANDLE>. i can't spot the error, but i think it might be around the print statements! can anyone help?? heres the code.
#! /usr/local/bin/perl -w use strict; open (FILEHANDLE, $ARGV[0]) or die "unable to open file"; open (OUTFILE, ">$$.output"); my $line; my @array; while (<FILEHANDLE>) { $line = $_; chomp ($line); @array = (); @array = split (/\s+/, $line); print STDOUT "$array[13]\t$array[14]\n"; print OUTFILE "$array[13]\t$array[14]\n"; } close FILEHANDLE; close OUTFILE; exit;
thanks :-)

Edit kudra, 2002-05-07 Changed title

  • Comment on Getting rid of uninitialized value warning (was: can't spot the error)
  • Download Code

Replies are listed 'Best First'.
Re: can't spot the error
by demerphq (Chancellor) on May 07, 2002 at 16:05 UTC
    Well its almost certainly that there is an undef in one of the values you are printing. Adding
    $array[13]="" unless defined $array[13]; $array[14]="" unless defined $array[14];
    Should sort you out.

    BTW, a more idomatic way to write your loop would be

    while (<FILEHANDLE>) { chomp; my @array=split/\s+/; $array[13]="" unless defined $array[13]; $array[14]="" unless defined $array[14]; print "$array[13]\t$array[14]\n"; print OUTFILE "$array[13]\t$array[14]\n"; }

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.

      An even more idiomatic way might be:
      while (<FILEHANDLE>) { chomp; my @array = split; next unless @array >= 15; ... }

      conv

        While I agree that your snippet is more idiomatic, it isnt the same thing as what the OP provided.
        $_=" a b c d e f g h"; @list=split/\s+/; print "split /\\s+/ : "; foreach my $i (0..$#list) { printf "%2d '%s', ",$i,$list[$i]; } print "\n"; @list=split; print "split : "; foreach my $i (0..$#list) { printf "%2d '%s', ",$i,$list[$i]; } print "\n"; __END__ split /\s+/ : 0 '', 1 'a', 2 'b', 3 'c', 4 'd', 5 'e', 6 'f', +7 'g', 8 'h', split : 0 'a', 1 'b', 2 'c', 3 'd', 4 'e', 5 'f', 6 'g', + 7 'h',
        And while I'm being pedantic :-) why do @array >= 15 when @array>14 does the same thing?

        *grin*

        Yves / DeMerphq
        ---
        Writing a good benchmark isnt as easy as it might look.

Re: can't spot the error
by hotshot (Prior) on May 07, 2002 at 16:04 UTC
    I think you shoud check your array before printing entries 13 and 14, I suspect they're indeed un initialized.
    Try doing:
    #! /usr/local/bin/perl -w use strict; open (FILEHANDLE, $ARGV[0]) or die "unable to open file"; open (OUTFILE, ">$$.output"); my @array; while (<FILEHANDLE>) { chomp; @array = (); @array = split(/\s+/); if (defined($array[13]) && defined($array[14])) { print STDOUT "$array[13]\t$array[14]\n"; print OUTFILE "$array[13]\t$array[14]\n"; }


    Thanks.

    Hotshot
Re: can't spot the error
by erikharrison (Deacon) on May 07, 2002 at 16:12 UTC

    Apparantly at some point $array[14] or $array[15] is empty. You get a slew of errors as this is repeated through the loop. Initialize each member of the array instead of setting it to empty - this will hitperformance but should clear your problem.

    On another note, please indent your code within the while block. :-)

    Cheers,
    Erik