Perl - 使用子例程方法计算文件中的字总数

时间:2015-03-12 10:55:11

标签: perl word-count

我试着计算文件中存在的单词总数。下面的代码显示0个字作为输出。请帮我解决这个问题。

此代码保存在Countsample.pm

package Countsample;

use strict;
use base"Exporter";
#use 5.010;

our @EXPORT=();
our @EXPORT_OK=qw(word_count);

sub word_count
{
    open(IP,"test1.txt");
    while(my $line=<>)
    my $word_count;


    my @words_on_line = split;
    $word_count+= @words_on_line;


    print"File contains $word_count words\n";
}

1;

现在在主程序中保存在Countsample1.pl

#!/usr/bin/perl

use Countsample qw(word_count);
word_count();
exit;

我得到的输出是

syntax error at Countsample.pm line 14, near ")
my "
Global symbol "$word_count" requires explicit package name at Countsample.pm line 14.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 18.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 21.
Compilation failed in require at Countsample1.pl line 3.
BEGIN failed--compilation aborted at Countsample1.pl line 3.

3 个答案:

答案 0 :(得分:2)

您需要为程序提供文件或输入。 E.g。

 perl Countsample1.pl Countsample.pm

会计算Countsample.pm

中的字数

此外,您需要while (my $line = <>)而不是open。你有没有注意到你从未读过任何东西?我假设这是家庭作业,所以我不会发布一个完全重写的脚本。

现在,您必须决定是仅计算test1.txt中的字数,还是命令行或STDIN上给出的任何内容(使用<>的含义)

假设后者,您的word_count子程序变得相当简单:

sub word_count {
    my $count;
    while (my $line=<>) {
        my @words_on_line = split ' ', $line;
        $count += @words_on_line;
    }
    print "File contains $count words\n";
    return; # don't accidentally use the return value of print as count
}

当然,最好只返回此子例程中的计数,并让调用者决定如何处理返回值。

PS:Your shebang line is wrong。如果您想使用系统#!/usr/bin/perl,则应为perl

PPS:您不需要继承Exporter。在大多数情况下,

use Exporter qw( import );

就是你所需要的一切。

PPPS:默认情况下不要导出内容。相反,做:

our @EXPORT = (); # nothing is exported by default
our @EXPORT_OK = qw( word_count ); # word_count is exported if asked

然后使用

use Countsample qw( word_count );

因此您可以Countsample::word_count调用word_count

答案 1 :(得分:2)

您的脚本中存在一些语法错误:

sub word_count {
    open(my $IP, '<', 'test1.txt') or die $!;
    #                              ^^^^^^^^^ always test the result of open                             
    my $word_count;
    # you must defined the counter outside of the while loop
    while(my $line=<$IP>) {
        #                 ^ you missed begin while bloc
        my @words_on_line = split ' ', $line;
        $word_count+= @words_on_line;
    } # and close while bloc
    # print the total outside of the loop
    print"File contains $word_count words\n";
}

答案 2 :(得分:1)

这是我得到的错误:

$ perl Countsample1.pl
syntax error at Countsample.pm line 14, near ")
    my "
Global symbol "$word_count" requires explicit package name at Countsample.pm line 14.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 18.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 21.
Compilation failed in require at Countsample1.pl line 1.
BEGIN failed--compilation aborted at Countsample1.pl line 1.

第13和14行是:

while(my $line=<>)
my $word_count;

您的while循环需要一段代码。代码块用大括号分隔。我认为那些行(以及以下几行)应该是:

my $word_count;
while(my $line=<>) {
    my @words_on_line = split;
    $word_count+= @words_on_line;
}

我还将my $word_count移到了循环之外 - 你真的不想在每次循环迭代时将它重置为零,对吗?

嗯..现在,当我跑它时,它只是挂起。可能有什么不对?这通常意味着无限循环或等待输入的程序。

在这种情况下,它是等待输入的程序。

while(my $line=<>)

这是从STDIN读取的(好吧,是的,实际上它是从STDIN或在命令行上传递的文件中读取的 - 但在这个例子中没有,所以它是STDIN)。据推测,您希望它从刚刚打开的文件句柄中读取。所以请改用它。

while(my $line=<IP>)

现在它没有挂起。但它说我的测试文件包含0个单词。那是错的。

问题出在这里啊。 my $line=<IP>将该行放入$line。但是您只使用split分割了该行,该行适用于$_,而不是$line。我们删除my $line=,以便while循环将数据放入$_

while (<IP>)

现在程序说我的文件包含5个单词。哪个好于零,但可能不对。所以可能存在逻辑问题。

现在你开始调试逻辑......

更新:实际上,没有。我的文件只包含五个单词。所以逻辑是合理的。是时候开始添加更多功能了。并且可能使代码现代化 - 例如用更现代的(open())替换旧式open(IP,"test1.txt")语句(open my $ip, '<', "test1.txt"))。另请检查open() - open my $ip, '<', "test1.txt") or die $!的返回值。