<Perl>参照配列の出力に失敗する。

このQ&Aのポイント
  • <Perl>参照配列の出力に失敗する。
  • 配列の出力部でエラーが発生し、未初期化の値を出力しようとしています。
  • CSVファイルからデータを取得し、配列に格納する際にエラーが発生しているようです。正しい出力方法を教えてください。
回答を見る
  • ベストアンサー

<Perl>参照配列の出力に失敗する。

<Perl>参照配列の出力に失敗する。 お世話になります。 配列の出力部で以下のエラーが出力されます。 Use of uninitialized value in print at test2.pl line 12. -----コーディングは以下の通りです。----- #!C:\perl use strict; use warnings; my @l = (); #----------- #GetDataへCSVファイル名と、格納用配列を渡す #----------- my $cnt = &GetData("test.csv", \@l); print "COUNT -> ".$cnt; for(my $i=0; $i < $cnt; $i++){ print $l[$i]; } ################################################################## # 概   要:指定したCSVファイルをオープンしCSVデータを配列に取得する。 # パラメータ:ファイル名, CSVデータ格納用配列 # 戻 り 値:データ取得件数 ################################################################## sub GetData { my ($f, @bf) = @_; my $rcnt = 0; print "FILE NAME -> ".$f."\n"; if ( open(FP, "<${f}") ){ print "FILE OPEN -> success.\n"; @bf = split(/,/, <FP>); close(FP); $rcnt = @bf; print "CSV GET COUNT -> ".$rcnt."\n"; } return $rcnt; } -----実行結果は以下の通りです。----- D:\>perl test.pl FILE NAME -> test.csv FILE OPEN -> success. CSV GET COUNT -> 5 Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. Use of uninitialized value in print at test2.pl line 12. COUNT -> 5 -----CSVファイルの内容は以下の通りです。(ファイル名:test.csv)----- あいうえお,かきくけこ,さしすせそ,たちつてと,なにぬねの 配列の要素数が取れているので、配列内にデータは格納されているとは思っています。 出力方法をどのように正せばよいがご教示お願い致します。

  • Perl
  • 回答数2
  • ありがとう数10

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

あ~.... 「参照がスカラー」というのは (その通りとはいえ) この文脈では適切じゃないなぁ. 訂正するためちょっと詳しく書いてみよう. GetData で my ($f, @bf) = @_; と引数を受けているので, $f がファイル名になり, @bf は「配列に対する参照 \@l を唯一の引数とする配列」です. で, 本当なら split した結果はこの参照を通して代入しなきゃならないのに @bf = split(/,/, <FP>); と配列そのものに入れている. つまり, 引数で渡された参照は全く使っていない. 「配列の要素数が取れている」というのは, この「ローカルな配列 @bf」であり, メインの配列 @l の要素数を調べれば「@l にデータが入っていない」ことはわかるはず. 訂正方法はいくつかあるけど自然なのは「参照はスカラー」なので my ($f, $bf) = @_; と参照もスカラーで受けること. それ以降は現状 @bf となっているのを参照経由で @$bf とすればいい. 念のため, 「参照」についてものの本で再確認した方がいいかもしれません.

t-uduki
質問者

お礼

Tacosanさん、ご指摘と、ご教示あるがとうございます!! *危なく、1つ前のレスにお礼を書くところでした。。。 ご指摘通り、参照の扱い方が間違っていました。 修正後は以下の通りです。 sub GetData { my ($f, $bf) = @_; #←単純配列の記載から先頭アドレス取得用の単純変数に変更 my $rcnt = 0; print "FILE NAME -> ".$f."\n"; if ( open(FP, "<${f}") ){ print "FILE OPEN -> success.\n"; @{$bf} = split(/,/, <FP>); #←単純配列の記載から参照配列用に変更 close(FP); $rcnt = @{$bf}; #←単純配列の記載から参照配列用に変更 print "CSV GET COUNT -> ".$rcnt."\n"; } return $rcnt; } ------- もう少し、Perlでのポインタの扱い方について勉強します…。 ありがとうございました!!

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「出力方法の問題」じゃない. 参照がスカラーだという事実を忘れている.

関連するQ&A

  • Perlで参照のクリアの方法

    Perlで参照のクリアで困っているのですが、以下のソースで正しくクリア方法はありますか? use strict; use warnings; use Data::Dumper; sub test { my ($arrayref) = @_; $$arrayref[2]{'A'} = 'aaaaa'; #$$arrayref = (); # Not a SCALAR reference at test_0042.pl line 10. $arrayref = (); #←クリアしているが、Dumperするとクリアされていない } my @A = (); print Dumper(@A); print "\n"; test(\@A); print Dumper(@A); print "\n"; exit; __END__ $VAR1 = undef; $VAR2 = undef; $VAR3 = { 'A' => 'aaaaa' };

    • ベストアンサー
    • Perl
  • DBMオープン時の警告

    既存のDBMファイルをオープンする処理で、 以下のような警告メッセージが出るのですが、 何が悪いのか、見当がつきません。 すみませんが、分かる方がいらっしゃいましたら、教えてください。 どの値が、なぜ、初期化されていないのでしょうか? Use of uninitialized value in dbmopen at b.pl line 4. Use of uninitialized value in null operation at b.pl line 4. オープン処理をするスクリプトは以下です。 #!/usr/bin/perl -w use strict; my %all = (); dbmopen %all, "all", undef or die "DBM open error"; foreach (keys %all) { print $_, "?t", $all{$_}, "?n"; } dbmclose %all; exit;

    • ベストアンサー
    • Perl
  • HASH(0xほげほげ)

    出力が”HASH(0x197fa1c)”のような場合、どう解析してけばいいでしょうか? --------------------------------------------------------------------- #!C:\Perl\bin\perl.exe -w use strict; use Win32::OLE::OPC; #変数↓ my $items_stringP1 = "PLC0"; #OPCServer のデバイス名 my $items_stringP2 = "D"; #MELSECのデバイス名称 my $items_stringP3 = 0; #先頭アドレス my $maxcount = 1; #点数(5) #変数↑ my $opcintf = Win32::OLE::OPC->new('OPC.Automation', 'Takebishi.Dxp'); my $group = $opcintf->OPCGroups->Add('grp'); my $items = $group->OPCItems; my $items_stringP3_Min = $items_stringP3; my $count = 0; while ($count < $maxcount){ my $items_string=$items_stringP1.".".$items_stringP2.$items_stringP3; $items_stringP3 ++; $count ++; $items->AddItem($items_string, $opcintf); } print "********************"."\n"; print $items ."\n"; print "********************"."\n"; my $key; foreach ( keys %$items) { print "キー値 : $key\n"; } --------------------------------------------------------------------- 出力結果:↓ ******************** Win32::OLE::OPC::Items=HASH(0x197fa1c) ******************** Use of uninitialized value $key in concatenation (.) or string at C:\testPerl\OPC\OPC08.pl line 38. キー値 : Use of uninitialized value $key in concatenation (.) or string at C:\testPerl\OPC\OPC08.pl line 38. キー値 : Use of uninitialized value $key in concatenation (.) or string at C:\testPerl\OPC\OPC08.pl line 38. キー値 :

    • ベストアンサー
    • Perl
  • perl 5.8.8 日本語マッチ

    perl5.8.8を使っています。 日本語にマッチする正規表現を書きたいのですが、どうしてもマッチしません。 例えば、以下のファイルtest.txtから「さしすせそ」だけを抽出し、表示させたいです。 ---------test.txt-------------------------------- あいうえお かきくけこ さしすせそ たちつてと -------------------------------------------------- ----------test.pl-------------------------------- use strict; use warnings; open(FILE, 'test.txt') or die "$!"; my @file = <FILE>; close(FILE); foreach my $line (@file){ if($line =~ /^さ/){ print "$line\n"; } } ------------------------------------------------ このtest.plを実行しても「さしすせそ」を抽出することが できません。 どうしたらよいのでしょうか? 自宅の新しいバージョンのperlだとできるのですが 会社のperlは5.8.8で顧客環境でもあるのでバージョンアップも できません。 すみませんが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • perl print文で日本語表示するには

    perlのプログラムで use utf8が宣言されていない時(test1.pl)は、 print文で日本語が正しく表示されるのですが、 use utf8が宣言されている時(test2.pl)は、 print文で日本語が正しく表示されないかエラーになります。 encode('utf-8', $string)やencode('cp932', $string) も試してみましたがうまくいきませんでした。 どのようにすればよいでしょうか。 ---test1.pl------------------------------------------------ #!C:/perl/bin/perl use strict; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon += 1; my $string="$year年$mon月$mday日 $hour時$min分$sec秒\n"; print $string; ----------------------------------------------------------- 実行結果 OK 2018年12月26日 9時36分6秒 ----------------------------------------------------------- ---test2.pl------------------------------------------------ #!C:/perl/bin/perl use strict; use utf8; use Encode; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon += 1; my $string="$year年$mon月$mday日 $hour時$min分$sec秒\n"; print $string; #print encode('utf-8', $string); #print encode('cp932', $string); --------------------------------------------------- 実行結果 NG (PC1 Windows7 ActivePerl) Wide character in print at D:\test\test2.pl line 11. Global symbol "$year年" requires explicit package name (did you forget to declare "my $year年"?) at D:\test\test2.pl line 8. Global symbol "$mon月" requires explicit package name (did you forget to declare "my $mon月"?) at D:\test\test2.pl line 8. Global symbol "$mday日" requires explicit package name (did you forget to declare "my $mday日"?) at D:\test\test2.pl line 8. Global symbol "$hour時" requires explicit package name (did you forget to declare "my $hour時"?) at D:\test\test2.pl line 8. Global symbol "$min分" requires explicit package name (did you forget to declare "my $min分"?) at D:\test\test2.pl line 8. Global symbol "$sec秒" requires explicit package name (did you forget to declare "my $sec秒"?) at D:\test\test2.pl line 8. Execution of D:\test\test2.pl aborted due to compilation errors. ----------------------------------------------------- 実行結果 NG (PC2 Windows7 ActivePerl) Malformed UTF-8 character (unexpected continuation byte 0x94, with no precedingstart byte) at C:\test\test2.pl line 8. (略) Malformed UTF-8 character (unexpected continuation byte 0x95, with no precedingstart byte) at C:\test\test2.pl line 8. 2018 N12 26 9 5 4 b ----------------------------------------------------- 期待している実行結果 2018年12月26日 9時36分6秒 ----------------------------------------------------- よろしくお願いします。

    • ベストアンサー
    • Perl
  • jcode.plのバグでしょうか?KCctchでの質問です。

    PerlのプログラムをKCatch.pmで調べていましたが。 次のような表示がされました。 jcode.plのバグでしょうか?プログラムに問題があるのでしょうか? お教えいただければ幸いです。 ../data/clients.txtが開けません。 Catch: Thu Jun 21 08:54:31 2001 -------------------------------------------------------------------------------- [jcode.pl:366:warn] Use of uninitialized value at jcode.pl line 366. > sub max { $_[ $[ + ($_[$[] < $_[$[+1]) ]; } [jcode.pl:362:warn] Use of uninitialized value at jcode.pl line 362. > $code = ('euc', undef, 'sjis')[($sjis<=>$euc) + $[ + 1]; -------------------------------------------------------------------------------- anquit.cgi with Perl 5.00502 for freebsd

    • ベストアンサー
    • Perl
  • [perl5.8] SJISで出力したはずのファイルにutf8フラグが

    1)SJISで以下の2行を含むファイルを作成し、   sjis.txtという名前で保存します。 "ホツカイドウ" "北海道" 2)SJISで以下のスクリプトを作成します。 #=== one.pl === use encoding 'Shift_JIS'; use open IN => ":encoding(Shift_JIS)"; use open OUT => ":encoding(Shift_JIS)"; my $infile = 'sjis.txt'; my $outfile = 'sjis2.txt'; open(IN, "<$infile"); @lines = <IN>; close(IN); open(OU, ">$outfile"); print OU @lines; close(OU); 3)SJIJSで以下のスクリプトを作成します #=== two.pl === use encoding 'Shift_JIS'; use open IN => ":encoding(Shift_JIS)"; use open OUT => ":encoding(Shift_JIS)"; my $infile = 'sjis2.txt'; my $outfile = 'sjis3.txt'; open(IN, "<$infile"); @lines = <IN>; close(IN); open(OU, ">$outfile"); print @lines; close(OU); 4)one.pl を実行し、続いてtwo.plを実行すると 以下のエラーがコマンドプロンプトに表示されます。 #------------------------------------------- D:\zipcode\utf8mondai>two.pl Wide character in print at D:\zipcode\utf8mondai\two.pl line 14. "・趣セゑスカ・イ・・セ橸スウ" Wide character in print at D:\zipcode\utf8mondai\two.pl line 14. "蛹玲オキ驕・ これは何故なのでしょうか。 エラーメッセージは、printしようとしている 文字列にutf8フラグがついているという意味 らしいです。

    • ベストアンサー
    • Perl
  • 配列内定義サブルーチン呼び出し

    下記のような配列内定義サブルーチン呼び出しを作成し動作を確認しました。 次にソース2行目の「no strict;」を「use script;」に変更すると Bareword "sub1" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub2" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub3" not allowed while "strict subs" in use at refsub_OK.pl line 4. Execution of refsub_OK.pl aborted due to compilation errors. とエラーになります。 プログラムはやはり「use script;」を記述したいのですが、「use script;」を記述 したままでエラーにならない方法がありましたらおしえてください。 perlのバージョンは5.12.3、OSはWindowsXP SP3です。 よろしくお願いします。 ---ソースここから--- #!perl no strict; use warnings; my @ary = ( ("input1.txt", "save1.txt", sub1), ("input2.txt", "save2.txt", sub2), ("input3.txt", "save3.txt", sub3), ); while (@ary) { my $p1 = shift(@ary); my $p2 = shift(@ary); my $sub = shift(@ary); print "p1=[$p1] p2=[$p2] sub=[$sub]\n"; &$sub("$p1", "$p2"); } sub sub1 { my ($p1, $p2) = @_; print "sub1: [$p1] [$p2]\n"; } sub sub2 { my ($p1, $p2) = @_; print "sub2: [$p1] [$p2]\n"; } sub sub3 { my ($p1, $p2) = @_; print "sub3: [$p1] [$p2]\n"; } ---ソースここまで---

    • ベストアンサー
    • Perl
  • csvファイルを配列へ格納しブラウザへ出力

    <?php #CAT csvファイルを開く $fp_c = fopen("test.csv","r"); #domain csvファイルを開く $fp_domain = fopen("test.csv","r"); print "<table border='1'>"; #fgetcsv関数がfalseを返却するまで実行 while($c_data = fgetcsv($fp_c)){ print "<tr>"; #csvファイルの列数だけ実行 for($i=0;$i<count($c_data);$i++){ print "<td>".$c_data[$i]."</td>"; } print "</tr>"; } print "</table>"; var_dump($c_data); fclose($fp); ?> このようなプログラムをつくってcsvファイルの各セルを配列$c_data[$i]へ格納している(つもり) なのですが、var_dump($c_data);を入れると bool(false)と表示されてしまいます。 このプログラムではcsvファイルの中身を表示できても配列に格納されていないのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • perl 配列名変数指定するには

    perlプログラムで for文で ループ分の配列定義するには どうしたらよいですか? 下記のようなことができないかと 考えております。 for(my $i = 0; $i < $file_no; $i++){ my @{"segments$i"} =(); #配列定義 my ${"line$i"}="";     #変数定義 my %{"hash$i"}= ();    #ハッシュ定義 open(ARG1,$ARGV[$i]); while(<ARG1>){ ${'line'.$i} = $_; chomp ${'line'.$i}; @{'segments'.$i} = split(/\t/,${'line'.$i});        ${'hash'.$i}{${'segments'.$i}[0]}=${'segments'.$i}[1];     } close(ARG1); } #下記で、その後 各ハッシュに設定したデータをもとに いろいろ計算したい foreach my $a (keys %{'hash'.$i}){ ・・・ } 今は、Can't declare array dereference in "my" at test.pl line XX, near "} =" と 配列定義でエラーとなり処理できません。

    • ベストアンサー
    • Perl

専門家に質問してみよう