• 締切済み

<STDIN>とARGVとの振る舞いの違いが分からず困っております。

<STDIN>とARGVとの振る舞いの違いが分からず困っております。 Perlといいますか、プログラム初心者です。 現在、Perlでファイル処理を行おうと思っており、下記のようなスクリプトを書き、file_test.plとして保存・実行しようとしたのですが、実行時の命令の仕方により処理が出来たり出来なかったりで、困っております。どなたか、ご教授頂けませんでしょうか。 なお、使用環境はWindows XP, Active Perl 5.8.8です。 スクリプトのソース、読み込みファイル共にShift-JISです。 (ここには記載しておりませんが、処理後の吐き出しファイルはUTF-8になります) -------------------- file_test.plのソースファイル -------------------- use strict; use warnings; use encoding "cp932"; use Encode::Guess qw/euc-jp shiftjis 7bit-jis/; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; my $csvname; if(defined($ARGV[0])){ $csvname = $ARGV[0]; print "csvname = $csvname\n"; #文字コード判定 my $enc = guess_encoding($csvname); ref($enc) or die "Can't guess: $enc"; print "encoding is ", $enc->name, "\n"; #UTF-8フラグチェック print utf8::is_utf8("$csvname") ? "UTF-8 Flag\n" : "not UTF-8 Flag\n"; } else{ print "input file: "; $csvname = <STDIN>; chomp($csvname); print "csvname = $csvname\n"; #文字コード判定 my $enc = guess_encoding($csvname); ref($enc) or die "Can't guess: $enc"; print "encoding is ", $enc->name, "\n"; #UTF-8フラグチェック print utf8::is_utf8("$csvname") ? "UTF-8 Flag\n" : "not UTF-8 Flag\n"; } open CSV, '<:encoding(sjis)', $csvname or die "$!"; print "FILE OPEN OK\n"; close(CSV); ------------------- file_test.plのソースファイル END ------------------- このソースを"perl file_test.pl csvfile.csv" で実行すると問題なく処理できます。 しかし、"perl file_test.pl" で実行し、あとからファイル名を入力すると、 "Invalid argument at file_test.pl line 35, <STDIN> line 1."というエラーが出ます。 (35行目はOPENコマンドの行です) しかし、 "perl -CA file_test.pl"と-CAオプションを入れ、後からファイル名を入力した場合、動作します(上述のファイルの実行と同時にファイル名を指定したものでも動きます)。 実際にはコマンドプロンプトからの実行ではなく、plファイルをダブルクリック、その後ファイル名を指定して処理を行いたいため、悩んでおります。 どのようにしたら、うまく実行できるか、ご教授頂ければ幸いです。

みんなの回答

回答No.2

例の$csvnameというのは、cp932のままでないと上手くいかないと思っていました。なので-CAオプションで utf8フラグを付けるとopenできるというのは説明ができません。 use encoding "cp932";とbinmode STDIN, ':encoding(cp932)';をはずすとどうなりますか use encoding "cp932"は binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; を3つするのとほぼ同じことなので、2箇所はずす必要がありました。

Luene
質問者

補足

2つを削除してみました。 うまく動作しました。ありがとうございます。 ただ、肝心のCSVファイルは読み込めなくなってしまいました。 CSVファイルを読み込むには、 use encoding "cp932"もしくは"shiftjis"が必要なようです。 他のbinmodeを削除し、encodingのみを入れると、コマンドライン上ではうまくファイルを読み込んでくれます。

回答No.1

コマンドラインでファイル名を与えたときは"not UTF-8 Flag"と出て、標準入力から与えたときは"UTF-8 Flag"と出ませんか? binmode STDIN, ':encoding(cp932)';を削ったらどうなりますか?

Luene
質問者

補足

早速のご回答ありがとうございます。 > コマンドラインでファイル名を与えたときは"not UTF-8 Flag"と出て、標準入力から > 与えたときは"UTF-8 Flag"と出ませんか? 出ます。しかし、-CAオプションを入れますと、両方ともUTF-8 Flagと出て、処理できます。 > binmode STDIN, ':encoding(cp932)';を削ったらどうなりますか? 実行結果に変化はありませんでした。 質問の際、文字数の制限で書けませんでしたが、実行結果を貼付します。 -----オプションなしで実行 (1) コマンドラインでファイル名指定 perl file_test.pl 201006.csv csvname = 201006.csv encoding is ascii not UTF-8 Flag FILE OPEN OK (2)標準入力でファイル名指定 perl file_test.pl input file: 201006.csv csvname = 201006.csv encoding is utf8 UTF-8 Flag Invalid argument at .\file_test.pl line 35, <STDIN> line 1. ----- CAオプションありで実行 (1) コマンドラインでファイル名指定 perl -CA file_test.pl 201006.csv csvname = 201006.csv encoding is utf8 UTF-8 Flag FILE OPEN OK (2)標準入力でファイル名指定 perl -CA file_test.pl input file: 201006.csv csvname = 201006.csv encoding is utf8 UTF-8 Flag FILE OPEN OK