我想使用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.
我无法弄清楚这个脚本有什么问题。有人可以帮我解决这个问题吗?
我甚至尝试使用getc
INPUT代替getc(INPUT)
。我认为在运行此脚本时我不需要包含任何其他包。
答案 0 :(得分:5)
while (<INPUT>)
将在循环的每次迭代中从INPUT
读取整行。如果要处理该文件一次处理一个char,则它不是正确的构造。
尝试类似:
my $c;
while (defined($c = getc(INPUT))) {
print $c, "\n";
}
答案 1 :(得分:2)
将文件读取运算符(< ... >
)与getc
混合是一个坏主意。它不是你想象的那样。
尝试将一些调试输出放入程序中以查看正在发生的事情。我通过自己运行它来测试程序(./getc getc
)。
在while
循环开始时,<INPUT>
会从您的文件中读取一行并将其存储在$_
中。然后使用getc
从文件中读取下一个字符。这将是你文件第二行的第一个字符(可能是换行符 - 可能是该行中唯一的字符)。
下一次循环,<INPUT>
读取下一行输入。这是use strict
行。 getc
从use warnings
读取下一个字符“u”。
所以它一直持续到文件的末尾。 <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";
}
}
但是将这两个人混在一起永远不会起作用。
答案 2 :(得分: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