pearl で use of uninitialized value エラーが出ます。最後の行の

print $filename[$x];のところです。なにが悪いのでしょうか。
use warnings;
$dpass='c:\\data\\';
#$count=0;
#$count2=0;
@ch_check = (1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
for ($x = 0; $x <= 15; $x++){
if ($ch_check[$x] == 1 ) {
if($x == 0){ $p_dat = 'CH1_*.log'; }
if($x == 1){ $p_dat = 'CH2_*.log'; }
if($x == 2){ $p_dat = 'CH3_*.log'; }
if($x == 3){ $p_dat = 'CH4_*.log'; }
if($x == 4){ $p_dat = 'CH5_*.log'; }
if($x == 5){ $p_dat = 'CH6_*.log'; }
if($x == 6){ $p_dat = 'CH7_*.log'; }
if($x == 7){ $p_dat = 'CH8_*.log'; }
if($x == 8){ $p_dat = 'CH9_*.log'; }
if($x == 9){ $p_dat = 'CH10_*.log'; }
if($x == 10){ $p_dat = 'CH11_*.log'; }
if($x == 11){ $p_dat = 'CH12_*.log'; }
if($x == 12){ $p_dat = 'CH13_*.log'; }
if($x == 13){ $p_dat = 'CH14_*.log'; }
if($x == 14){ $p_dat = 'CH15_*.log'; }
if($x == 15){ $p_dat = 'CH16_*.log'; }
$p2_dat = $dpass.$p_dat;
print $p2_dat;
$filename[$x] = glob $p2_dat;
}
else{
$filename[$x] = "no_file";
}
print $filename[$x];
# print \n;
}

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2008/04/27 19:05:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:al001 No.1

回答回数14ベストアンサー獲得回数1

ポイント27pt

$filename[$x] = glob $p2_dat; の行にて $filename[$x]に何も代入されなかったにもかかわらず、

print $filename[$x]と$filename[$x]を出力しているためかと思います。

ためしにその行を$filename[$x] = "test";にしてみるとエラーは消えるかと。


原因はglob $p2_datにてファイルが見つからなかったことだと存じます。

ファイルが見つからなかったときも$filename[$x]に何か値を入れるか、

もしくはファイルが見つからなかったとき、つまり$filename[$x]に何も入っていなかったときは出力を控えるようにすれば解決するかと存じます。

$filename[$x] = glob $p2_dat;

の部分を以下のようにしたらどうでしょうか。

以下はファイルが見つからなかったとき$filename[$x]に"ファイル無いよ。"を代入するコードです。

if (my $result = glob $p2_dat) {
  $filename[$x] = $result; 
} else {
  $filename[$x] = "ファイル無いよ。";
}

もしくは

print $filename[$x];

print $filename[$x] if $filename[$x];

にすれば$filename[$x]に何も入っていないときは$filename[$x]が出力されないので、解決されるかと存じます。

URLはダミーですが、僕が愛用しているperlサイトのglobの説明です。

http://www.rfs.jp/sb/perl/05/glob.html

いちお差し替えコードは動作確認済みです。

id:youkan_ni_ocha

回答ありがとうございます。ファイルが無いというご指摘ですが、ファイルはあります。で$filename[$x]を@filename[$x]という禁じ手を使うと、警告はでるものの、ファイルが表示されます。どーもよくわかりません。if***とやたらに続いてるのは *を使うと、いまいち挙動がおかしくなるようなので入れてあります。なんか気持ちわるいです。。、、どうも、根本的な問題のような気がします。

2008/04/20 19:55:15
id:al001 No.2

回答回数14ベストアンサー獲得回数1

ポイント27pt

先ほど回答させていたコードを再度テストしましたが、手元ではきちんとファイルネームが表示されました。

テスト環境はWindows XP SP2、Active Perl 5.8.8。

C:\test.plに問題のコードを置き、C:\data以下にCH1_test.log、CH1_test2.logを配置しました。


解決方法を提示できておらず申し訳ないのですが、

ディレクトリ構造やOS、Perlのバージョンなどを教えていただけるとお力になれるかもしれません。

自分の環境で動いたので、globに突っ込んでる文字列に合致するファイルが無いことを疑ってます。(すみません。。)

CH1_test.logという名前のファイルを、C:\data\に作って再度ファイル名が表示されないか試していただけると幸いです。

http://google.com/

id:youkan_ni_ocha

active perl 5.10.0.1002 xp home edition sp2だとおもいます。perlのバージョンが少し違うようですね。

プログラムは、デスクトップのマイドキュメント\perl_programにおいて、perlをはじめようという開発環境で実行しています。perlはデフォルトのディレクトリにあります。正式なファイル名はたとえばCH1_2008_4_10_T10_23_33.logというような長ったらしい名前です。globにファイル名がわたされるときに、なんらかの文字化けがおきるという可能性は否定できないかと思います。*が嫌というか、気になります。ファイル名を変える実験はのちほど

2008/04/20 21:22:17
id:imo758 No.3

回答回数121ベストアンサー獲得回数19

ポイント26pt

このような場合、grob演算子の受け取りはリストにしておいた方が賢明です。つまり

$filename[$x] = glob $p2_dat;
↓
@filename[$x] = glob $p2_dat;

$filename[$x] = "no_file";
↓
@filename[$x] = ("no_file");

print $filename[$x];
↓
print @filename[$x];

となります。

グロブは新しいリストを開始するときにだけ、(埋め込まれた)引数を評価します。再び始めからやり直す前に、すべての値を読み終わっていなくてはなりません。grobを呼び出すたびに次の値が返され、読んでしまったら偽が1回だけ返されます。

しかしこれはスカラーコンテキストの場合のみで、リストコンテキストでは問題になりません。

id:youkan_ni_ocha

連続してファイルを読み出したとき、エラーが1回おきにおきる理由がようやく理解できました。

2008/04/21 10:23:53
  • id:imo758
    すいません間違えました。@~ を @{$~} に直してください。
  • id:imo758
    $filename[$x] = glob $p2_dat;

    @{$filename[$x]} = glob $p2_dat;

    $filename[$x] = "no_file";

    @{$filename[$x]} = ("no_file");

    print $filename[$x];

    print @{$filename[$x]};
  • id:imo758
    あくまで憶測ですが、globこのような仕様になっているのは、おそらく
    while(<log_*.txt>){ # while(glob "log_*.txt"){ と同じ
      ~
    }
    のようなコードを書けるようにするためだと思われます。
  • id:al001
    見当違いなこと言った上に混乱させてしまって申し訳ありません。。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません