0

Perlを使用してメッセージ内の文字の出現頻度を計算したいと思います。たとえば、char "a"がメッセージに10回出現する場合、頻度は10になります。これを行うには、getc関数を使用して一度に1文字ずつ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)ました。このスクリプトの実行中に他のパッケージを含める必要はないと思います。

4

3 に答える 3

5
while (<INPUT>)

INPUTループの各反復でから行全体を読み取ります。そのファイルハンドルを一度に1文字ずつ処理する場合は、使用するのに適切な構造ではありません。

次のようなものを試してください:

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

ファイル読み取り演算子(< ... >)をと混合するgetcことはお勧めできません。それはあなたが思っていることをしていません。

デバッグ出力をプログラムに入れて、何が起こっているかを確認してください。プログラムを実行してテストしました(./getc getc)。

whileループの開始時に、は<INPUT>ファイルから行を読み取り、それをに格納します$_。次に、を使用getcしてファイルから次の文字を読み取ります。これは、ファイルの2行目の最初の文字になります(おそらく改行文字-その行の唯一の文字である可能性があります)。

次回ループを回るとき、<INPUT>は入力の次の行を読み取ります。それがuse strictラインです。は、から「u」である次のgetc文字を読み取りますuse warnings

そして、それはファイルの終わりまで続きます。は<INPUT>1行をgetc読み取り、次には次の行の最初の文字を読み取ります。

それはあなたが望むものではありません。一度に1文字ずつ読みたい場合は、が必要ですgetc

#!/usr/bin/perl

use strict;
use warnings;

my $input = shift;

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

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

もう1つの方法は< ... >、各行を読みながら使用して分割することです。

#!/usr/bin/perl

use strict;
use warnings;

my $input = shift;

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

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

しかし、アプローチされた2つを混合することは決してうまくいきません。

于 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 に答える