2016-07-19 11 views
0

私は、ファイルを開いて読み込み、行を解析して新しいファイルに書き込む関数を持っています。私はこのファンクションを別のファイルで何回か呼びます。しかし、今私は気づいた、すべての新しい関数呼び出しでは、以前のファイルの行も読み込まれます。どうすればそれを防ぐことができますか? es.txtの古い内容のperlを残さずに別のファイルから読み取る

内容:dt.txtの El anarquismo es una filosofía política y social que llama

内容: der Regel mit Veränderungen der chemischen Bindungen in

プログラムの実行後に、それが唯一のDT」からのトークンが含まれている必要がありますが、作成されたファイルProfileDEは(次のようになります.txtファイルes.txt "」、いくつかのトークンからのものである"):

una 
ilos 
ism 
lític 
qui 
lí 
ti 
polí 
socia 

- 実際のコード:

#! /usr/bin/perl 
use utf8; 
use warnings; 
use strict; 
use List::Util qw(min); 
use open ':encoding(utf8)'; 
binmode(STDOUT, ":utf8"); 
binmode(STDIN, ":utf8"); 

generateProfile("es.txt", "ES"); #function call to read from file es.txt 
generateProfile("dt.txt", "DE"); #second call to read only from file dt.txt 

sub generateProfile { 
    my $file= $_[0]; #taking arguments 
    my $Lang = $_[1]; 

    open(IN, "<:utf8",$file) || die "error"; #to read file 
    open(OUT, ">:utf8", "profile$Lang.txt"); # to create and write in file e.g profileDe 

    my (%ngramL); #any hash for later 
    my $line; 
    my (@words); 
    my (%ngramL); 
    my (@uni, @bi, @tri, @quad, @five); #array which keeps letterkombinations of different length 

    while($line =<IN>){ 
     chomp $line; 
     # print $line; # just for testing: during the second function call, it would print here old content from "es.txt" instead of only reading from "dt.txt" 
     push(@words, $line); 
     } 
    close IN; #doesn't it closed? 

    foreach my $word (@words){ 
     bigramm($word); #split word in different letter combinations 
     } 

    freqL(); #fill that hash with frequences, how many times occures one letter combination e.g. "ab" = 2, "tion"=5 
    print_hashL(); #print hash 

    sub bigramm{ 
     my $wort= $_[0]; 
     my $i; my $k; 
     my @letters= split(//, $wort); 
     for ($i=0; $i<length($wort)-0; $i++){ ####!!!!! -1? 
     my $bi= substr($wort, $i, 1); 
     push(@uni, $bi); } 
     for ($i=0; $i<length($wort)-1; $i++){ 
     my $bi= substr($wort, $i, 2); 
     push(@bi, $bi); } 
     for ($i=0; $i<length($wort)-2; $i++){ 
     my $bi= substr($wort, $i, 3); 
     push(@tri, $bi); } 
     for ($i=0; $i<length($wort)-3; $i++){ 
     my $bi= substr($wort, $i, 4); 
     push(@quad, $bi); } 
     for ($i=0; $i<length($wort)-4; $i++){ 
     my $bi= substr($wort, $i, 5); 
     push(@five, $bi); }  

} 

    sub freqL{ 
     for my $duo (@uni, @bi, @tri, @quad, @five){ 
     if(defined $ngramL{$duo}) {$ngramL{$duo}++;} 
     else {$ngramL{$duo}=1;} 
    } 
    } 

    sub print_hashL{ 
     foreach my $elem(sort{$ngramL{$b}<=>$ngramL{$a}} keys %ngramL) { 
     print OUT "$elem\n";} 
    } 

} 

この問題が発生するかどうかは、いくつかの警告がありますか? :

"my" variable %ngramL masks earlier declaration in same scope at stack.pl line 23. 
Variable "@uni" will not stay shared at stack.pl line 46. 
Variable "@bi" will not stay shared at stack.pl line 49. 
Variable "@tri" will not stay shared at stack.pl line 52. 
Variable "@quad" will not stay shared at stack.pl line 55. 
Variable "@five" will not stay shared at stack.pl line 58. 
Variable "@uni" will not stay shared at stack.pl line 63. 
Variable "@bi" will not stay shared at stack.pl line 63. 
Variable "@tri" will not stay shared at stack.pl line 63. 
Variable "@quad" will not stay shared at stack.pl line 63. 
Variable "@five" will not stay shared at stack.pl line 63. 
Variable "%ngramL" will not stay shared at stack.pl line 64. 
Variable "%ngramL" will not stay shared at stack.pl line 70. 
+0

この部分は大丈夫です。 'bigramm'サブはグローバル変数か状態変数を使用していますか?私は、bigrammキャッシュが(グローバルに、または状態変数で)その入力を受け取り、その後キャッシュをクリアしないと思います。 – dgw

+1

私はサブシステム内のサブシステムの専門家ではありませんが、サブシステムの外側で 'my(@words、%ngramL、@uni、@bi、@tri、@quad、@five)を宣言し、' 'generateProfile'を呼び出すと、あなたの問題を解決します。それは迅速な修正のためのものですが、私はより多くの経験/知識を持つ人により正確な回答を投稿できるようにします。私の推測では、他のサブシステム内のサブシステムは一度だけコンパイルされ、それらの外部で宣言された配列/ハッシュは内部変数をグローバル変数に変換されているということです...しかし、それはちょっと推測しています – Dada

+0

私はコード全体を改造しました。私はコードをそのままにしておくと、クイックフィックスも機能しましたが、generateProfile( "en.txt"のような他の関数呼び出しを1つ追加するだけです。 "、" EN "); –

答えて

0
while($line =<IN>){ 
    chomp $line; 
    print $line; # during the second function call, it would print here old content from "es.txt" instead of only reading from "dt.txt" 
    push(@words, $line); 
    close IN; #doesn't it closed? 

あなたが入力ファイルから1行を読んだ後、あなたは基本的にFileHandlerのを閉じます。次に、2行目に行くと、前に閉じたのでファイルから読み込むことができなくなります。

+0

いいえ、私は申し訳ありませんが、これはコピー貼り間違いです。 "}"をそこに置くのを忘れました。 –

+0

どうやって "このfunktionを別のファイルで何回か呼び出す"のですか?コード例? –

+0

ここでは、これらの行が異なるファイルで関数を呼び出すことを意味しています。 (1)generateProfile( "es.txt"、 "ES"); (2)generateProfile( "dt.txt"、 "DE"); パラメータは変更されていますが、(1)を呼び出した後、2番目の呼び出しのストリームは最初のファイルを覚えているように見え、(1)から(2)までの行を印刷します。 –

関連する問題