I’ve got a question in my test:
What is wrong with program that counts number of lines and words in file?
open F, $ARGV[0] || die $!;
my @lines = <F>;
my @words = map {split /\s/} @lines;
printf "%8d %8d\n", scalar(@lines), scalar(@words);
close(F);
My conjectures are:
- If file does not exist, program won’t tell us about that.
-
If there are punctuation signs in file, program will count them, for example, in
abc cba , , ,dcewill be five word, but on the other hand
wcoutputs the same result, so it might be considered as correct behavior. - If
Fis a large file, it might be better to iterate over lines and not to dump it intolinesarray.
Do you have any less trivial ideas?
On the first line, you have a precedence problem:
is the same as
which means the
dieis executed if the filename is false, not if theopenfails. You wanted to sayor
Also, you should be using the 3 argument form of open, in case
$ARGV[0]contains characters that mean something toopen.On a different note, splitting on
/\s/means that you get a “word” between consecutive whitespace characters. You probably meant/\s+/, or as amphetamachine suggested,/\W+/, depending on how you want to define a “word”.That still leaves the problem of the empty “word” you get if the line begins with whitespace. You could split on
' 'to suppress that (it’s a special case), or you could trim leading whitespace first, or insert agrep { length $_ }to weed out empty “words”, or abandonsplitand use a different method for counting words.Processing line by line instead of reading the whole file at once would also be a good improvement, but it’s not as important as those first two items.