1

I am trying to learn perl programming and am using it to read a file from a contest;

#!/usr/local/bin/perl
use warnings;

open(FILE, <~/source/test.txt>);
@array = <FILE>;
$number = shift @array;

while($number--) {
    chomp($key = shift @array);
    chomp($message = shift @array);

    print "Key: $key";
    print "Message: $message";
}
print "\n";
close(FILE);

The file contains a number, N, then there are 2 * N lines that follow which is how many key/message pair's there are.

But when I do this program, it only prints out the last "message" and nothing else... it doesn't print anything else. If I remove the chomps it works as intended, but with the chomps there it just cuts everything off... any ideas why?

//EDIT: removed the -w

Nicholas
  • 7,403
  • 10
  • 48
  • 76
  • your first line should be number of lines in the file and each key and message must be in a new line – run Nov 07 '11 at 04:22
  • You should use strict. [Why use strict and warnings?](http://stackoverflow.com/q/8023959/725418) – TLP Nov 07 '11 at 04:30
  • The `-w` is more or less redundant with `use warnings;`. `-w` enables warnings for any modules as well, which is considered a bad idea these days (since some older modules might not work properly with warnings enabled). Suggestion: Use `use stricts; use warnings;` and drop the `-w`. – Keith Thompson Nov 07 '11 at 04:42
  • @run, I didn't create the contest... that's the way they describe it, first line is the number of key/message pairs. – Nicholas Nov 07 '11 at 15:52

1 Answers1

8

You are reading a DOS/Win text file on a unix box. Using chomp, you are removing the "LF" of "CRLF", but leaving the "CR", causing all your lines to be shown one atop the other.

#!/usr/local/bin/perl -w
use strict;   # Do use this!
use warnings;

open(my $fh, '<', "$ENV{HOME}/source/test.txt") or die $!;
my @array = <$fh>;
s/\s+\z// for @array;  # Universal chomp

my $number = shift(@array);
while ($number--) {
   my $key     = shift(@array);
   my $message = shift(@array);

   print "Key: $key\n";
   print "Message: $message\n";
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    `s/\s+\z//` also removes trailing blanks and tabs, which may or may not be what you want. – Keith Thompson Nov 07 '11 at 04:41
  • @Keith Thompson, Indeed, but if you have to deal with a format that relies on meaningful trailing whitespace, I pity you. – ikegami Nov 07 '11 at 05:12
  • So I should use `my`. I keep looking for tutorials and some reference `my` and some don't for variables... can anyone point me to a decent, recent perl tutorial? – Nicholas Nov 07 '11 at 05:21
  • @Nicholas, `my` creates varaibles with a limited scope. Limiting the scope of variables is a basic Computer Science tenet, so I don't know of any tutorial that covers that specifically. You should be using `use strict;` to have Perl tell you when you forgot to declare (or mispelled) a variable (and a couple of other super useful checks). – ikegami Nov 07 '11 at 06:36
  • 1
    @Nicholas : For Perl tutorials you might begin here: [tutorials](http://perl-tutorial.org/) – JRFerguson Nov 07 '11 at 13:14
  • @ikegami, I know about scope. Just the tutorials I was reading were all over the place, with some advocating `my` and some not using it. I should have researched it more in depth I guess. thanks for the advice – Nicholas Nov 07 '11 at 15:43
  • @Nicholas, I don't know who you saw not using it, but try not using their tutorials :) – ikegami Nov 07 '11 at 18:45