- ベストアンサー
(Perl)UTF-8で別ファイルに書き出したい
- 現在、jcode.plを使用したShift JISで構成されていた Perlのcgi を UTF-8 に改造しています。
- 複数ある別ファイルからデータ読み込む場合も、open(IN,":utf8","$別ファイル"); という形で、うまく読みこめています。
- 書きこんだファイルを開けてみると、日本語が文字化けしています(アルファベットは大丈夫)
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
stdio::getFormDataに対しての見識がないので適切な回答はできませんが、以下を試すとどうなるでしょうか? %in = (); stdio::getFormData(\%in,1,"sjis",1,",","$updir/"); を、 use CGI; %in = map decode_utf8($_), CGI->new->Vars; に変更。 これで文字化けが解消する可能性はありますが、stdio::getFormDataに詳しい人が回答してくれるかもしれませんので、質問はオープンのままにされたほうがいいと思います。
その他の回答 (3)
- ryu_chan
- ベストアンサー率37% (69/186)
No.2のTacosanさんが言及されてますが、以下で解決できるかもしれません。 use Encode; for my $value ( values %in ) { $value = decode_utf8 $value; }
お礼
ryu_chanさま ご回答ありがとうございました。 上記コードも試しましたが、文字化けは解消されませんでした(>_<)。 冒頭で以下のような宣言をしていますが、これが問題になっているのでしょうか? #------------------------------------------------- # 受け取ったデータの変換 #------------------------------------------------- %in = (); stdio::getFormData(\%in,1,"sjis",1,",","$updir/");
補足
もしくは、別ファイルで行っている以下のデコード処理が問題なのでしょうか? ※sjisの部分はコメントアウトしています。 #------------------------------------------------- # デコード処理 #------------------------------------------------- sub DECODE { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/, $pair); $name2 = $name; $value2 = $value; $FORM2{$name} = $value; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; #半角カナを全角に変換 # Jcode::h2z_sjis(*value); #文字コード変換 # Jcode::convert(*value,'sjis'); $value =~ s/</</g; $value =~ s/>/>/g; $value =~ s/\n/!%/g; $value =~ s/\r//g; $value =~ s/\t//g; $value =~ s/\,/&%/g; $value =~ s/ / /g; #フォーム変数へ $in{$name} = $value; } }
- Tacosan
- ベストアンサー率23% (3656/15482)
%in の文字コードか? Encode::decode でなんとかなるかも....
お礼
ご回答ありがとうございました。 早速試してみましたが、ダメでした。
- N60-BASIC
- ベストアンサー率80% (17/21)
惜しいところまで行ってますね。 if( !open(OUT,">$linkdata_file") ){ &ERROR( read_linkdata ); } を、Perl5の新機能である「3引数open」を使って if( !open(OUT,">:utf8", $linkdata_file) ){ &ERROR( read_linkdata ); } としてみたらどうでしょうか? use utf8; で書かれたスクリプト内文字列や、Encode.pm でデコードされた文字列は、内部utf8表現とでも言うべき特殊な文字列になっています。 この内部utf8表現の文字列は、そのまま標準出力やファイルに対してストリーム出力しようとすると、 Wide character in print at ... といった感じの警告が出てしまいます。 これを正常にUTF-8で出力するには、内部utf8表現をUTF-8バイトコード文字列に変換してやる必要があります(「内部表現」と言われる理由です)。 本来は出力したい文字列に対してEncode::encode()を明示的に使うのですが、使わなくても自動でやってくれるのが出力オープン時の「:utf8」指定になります。 この辺、仕組みをきちんと理解しようとすると非常にややこしい部分ではあるのですが、一見面倒に見えるこの仕組みのおかげで、文字化け等を気にせずに正規表現などを利用できるようになります。 正確には、内部utf8表現を使うことで「半角英数字以外の文字についてもPerlがすべての文字を1文字単位で扱ってくれるようになる」といったところでしょうか。 興味がありましたら「Perl utf8フラグ」あたりで検索してみるとよいかもしれません。 あと余談ですが、もし前回の私の回答がきっかけでPerl5を勉強してくださってるのだとしたら本当に頭が下がります。 以下のblog記事が「今どきのPerlスクリプト」を知る上で多少参考になるかもしれません。 [ サンプルコードによるPerl入門 - 現代的なPerlの記述方法一覧 ] http://d.hatena.ne.jp/perlcodesample/20091120/1246679588 ご参考まで。
お礼
N60-BASIC様 またご回答頂きましてありがとうございました。 m(_ _)m 詳細なご説明でとてもよく分かりました! 参考URLも大変参考になりました! アドバイス通り open(OUT,">:utf8", $linkdata_file) と記載してみました。 正常に動作はしましたが、残念ながら文字化けはまだ直りませんでした。 文字化け状況 → ããããã このPerlは、フォームに日本語等の文字入力して、実行ボタンを押すと $linkdata_file に、そのデータを書き込みます。 フォームに入力する時は、普通に日本語で表示されていますが、 どうやら、「実行ボタン」を押して、書き込んだ時に文字化けが発生しているようです。 そのため、$linkdata_fileに書き込まれたデータをフォーム上で再編集しようと$linkdata_fileから読み込んだ場合に、文字化けされた文字が反映されてしまうという状況になっています。 なお、ブラウザ上のフォーム自体は、文字コードがutf-8に既にセットされています。 linkdata_file内のデータを除くと、日本語のみが文字化けしていました。 もしかすると原因は、 $in{'LINKNAME'} =~ s/\,/&%/g; $in{'LINKURL'} =~ s/\,/&%/g; $in{'LINKURL'} =~ s/&/\&/g; $in{'COMMENT'} =~ s/\,/&%/g; $in{'COMMENT'} =~ s/\<br \/\>/!%/g; の設定にあるのでしょうか? お手数をおかけいたしますが、ご教示お願いします。 m(_ _)m
お礼
ryu_chanさま ご教示誠にありがとうございました! ご指摘の通り、修正したところ、文字化け直りました!!! m(_ _)m 感動しました!(^^) まるで魔法のような感じ驚いています。 かれこれ3日間くらい格闘してきましたが、問題が解決できてスッキリしました。 誠にありがとうございました!感謝致します。
補足
N60-BASIC様、Tacosan様、ryu_chan様、誠にありがとうございました。 各皆様のおかげで問題が解決ができまして、大変感謝しております。 今回は、ずばり直ったryu_chan様をベストアンサーとさせて頂きますので、どうぞご了承ください。 実は、もう1つだけ同じ文字化けの現象が起きていて、解決できない問題があります。(もう1つ質問を立てさせて頂ければと思います。 もし宜しければ、再度アドバイスを頂ければと思いますので、どうぞよろしくお願い致します。