• ベストアンサー

[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フラグがついているという意味 らしいです。

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

  • ベストアンサー
回答No.2

use encodingプラグマは、これから開かれるファイルハンドルの文字コードを明示的に示します。 そしてファイルハンドルから読み込む時に「フラグ付きUTF-8」に変換して変数に格納し、 書き出す時は「フラグ付きUTF-8」から指定の文字コードに変換、と言う動作を自動的に行うようになります。 これはこの後から開くファイルハンドルにのみ有効です。 すなわちuseした時点で既に開かれているSTDIN,STDOUT,STDERRはuse encodingの影響を受けません。 なので、STDOUTに出力しているtwo.plの print @lines; はUTF-8フラグつきの文字列をそのまま出力しようとしてしまうので、質問のような警告が発生します。

ibayac
質問者

お礼

print OU @lines のように、ファイルに出力するようにしたところ、解決しました。 (回答No.1のkomorebi99さんに嘘を答えてしまいました。すみません。例の箇所をOUにして試しましたが、その際、別の行にもprint文があって、そこがエラーになっていました) 大変参考になりました。ありがとうございました。

その他の回答 (2)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>open(OU, ">$outfile"); >print @lines; >close(OU); open(OUT, ">$outfile"); print OUT @lines; close(OUT); の間違いだと思います。 print @lines; のままで、標準出力のコンソール出力が化けてしまうということなら binmode STDOUT, ":raw:encoding(shiftjis)"; を標準出力を使う前に、実行して下さい。

ibayac
質問者

お礼

two.plを以下の様に変更したところ、画面(標準出力)上でも問題なくprint結果を見られるようになりました。 自分がちょっとしたデバッグライトは画面に出すのが 好きなので、大変助かります。 #=== two.pl === use encoding 'Shift_JIS'; use open IN => ":encoding(Shift_JIS)"; use open OUT => ":encoding(Shift_JIS)"; binmode STDOUT, ":raw:encoding(shiftjis)"; my $infile = 'sjis2.txt'; my $outfile = 'sjis3.txt'; open(IN, "<$infile"); @lines = <IN>; close(IN); print @lines; 結局、ファイル形式がone.plでおかしくなっていた のではなく、ファイルプラグマだけ指定した状態で ファイル以外にprintしていた事が原因だったわけ ですね。質問のタイトル、今考えるとおかしいですね。 正しく問題を理解することができました。 ありがとうございました。

回答No.1

two.plを見ますと、最後の3行の中の2行目 print @lines; これは、「 OU 」が抜けていませんか? print OU @lines; ではないかな…と思うのですが… one.plとtwo.plの違いはここだけですよね? とりあえず OUを入れると動きますけど、最終的に何を為さりたいのかはわかりませんが…。(^^;

ibayac
質問者

お礼

返信ありがとうございます。 やりたい事は、元ファイルの加工です。 加工内容が複雑ですので、何回かに分けてスクリプト をかませようとしています。 業務ロジックは複雑ですので、簡略化して質問をした次第です。 私の環境では、OUを入れても動きません。同様のエラーがでます。 どうしてShift-JISの文字コードをprintするとutf8にまつわるエラーになるのか、その原因が知りたいです。

関連するQ&A