为什么我的程序使用Perl的getc函数不能正常工作?

时间:2011-10-16 09:48:52

标签: perl getc

我想使用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)。我认为在运行此脚本时我不需要包含任何其他包。

3 个答案:

答案 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行。 getcuse 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