0

我想使用 Perl 计算消息中字符出现的频率。例如,如果字符“a”在一条消息中出现 10 次,那么频率将为 10。为此,我使用getc函数一次从一个 FILE 读取消息。这是我写的片段。这是非常基本的,我知道。但是当我编译时,我得到一个错误:

细节:

#!/usr/bin/perl

use strict;
use warnings;

my $input=$ARGV[0];

open(INPUT,"<$input");

while(<INPUT>
{
 my $c=getc(INPUT);
 print $c."\n";
}

close(INPUT);

尝试编译时出现以下错误:

Use of uninitialized value in print at AccessChar.pl line 13, <INPUT> line 1.

我无法弄清楚,这个脚本有什么问题。有人可以帮我解决这个问题吗?

我什至尝试过使用getcINPUT 而不是getc(INPUT). 我认为在运行此脚本时不需要包含任何其他包。

4

3 回答 3

5
while (<INPUT>)

INPUT将在循环的每次迭代中读取一整行。如果您想处理该文件一次处理一个字符,那么它不是正确的构造。

尝试类似:

my $c;
while (defined($c = getc(INPUT))) {
  print $c, "\n";
}
于 2011-10-16T09:56:01.283 回答
2

将文件读取运算符 ( < ... >) 与混合使用getc是个坏主意。它没有做你认为的那样。

尝试将一些调试输出放入程序中,看看发生了什么。我通过在自身上运行程序来测试程序(./getc getc)。

while循环开始时,<INPUT>从文件中读取一行并将其存储在$_. 然后,您可以使用getc从文件中读取下一个字符。这将是文件第二行的第一个字符(可能是换行符 - 这可能是该行上的唯一字符)。

下一次循环时,<INPUT>读取下一行输入。就是这样use strictgetc读取下一个字符,即来自 的 'u ' use warnings

所以它继续到文件的末尾。<INPUT>读取一行,然后从getc下一行读取第一个字符。

这根本不是你想要的。如果您想一次读取一个字符,那么您只需要getc.

#!/usr/bin/perl

use strict;
use warnings;

my $input = shift;

open(my $file, '<', $input);

while (defined(my $c = getc $file)) {
  print "$c\n";
}

另一种选择是在< ... >阅读时使用并拆分每一行。

#!/usr/bin/perl

use strict;
use warnings;

my $input = shift;

open(my $file, '<', $input);

while (<$file>) {
  foreach my $c (split //) {
    print "$c\n";
  }
}

但是将这两种方法混合起来永远不会奏效。

于 2011-10-16T11:23:50.590 回答
1

只是为了一点 TIMTOWTDI:

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper;

local $/;
my %chars;

$chars{$_}++ for split //, <>;

print Dumper \%chars;

只要文件不是太大而不能啜饮,它就可以工作;如果是读取并拆分每一行。用法:

$ count_chars.pl file_to_read
于 2011-10-17T03:11:16.023 回答