![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
現在、jcode.plを使用したShift JISで構成されていた Perlのcgi を UTF-8 に改造しています。
冒頭で use utf8; を宣言した後、jcode関連の文は、全てコメントアウトしてきました。
複数ある別ファイルからデータ読み込む場合も、
open(IN,"<:utf8","$別ファイル"); という形で、"<:utf8"を挿入して、うまく読みこめています。
ただ、読み込んだ後、別ファイルへUTF-8で書きこむのが、どうしてもうまくいきません。
書きこんだ後、文字化けしてしまいます。
書きこんだファイルを開けてみると、日本語が文字化けしています(アルファベットは大丈夫)
以下のPerlをどのように改造すれば、文字コードをUTF-8で書き込みすることができるのでしょうか?
どうかご教授、よろしくお願い致します。
m(_ _)m
---------------------------------
#-------------------------------------------------
# 編集内容登録処理
#-------------------------------------------------
sub EDITREGIST {
#全角英数字を半角に変換
$zenkaku = '0123456789';
$hankaku = '0123456789';
#Jcode::tr(\$in{'CLICK'}, $zenkaku , $hankaku );
$in{'attach_file'} = &AttachCheck($attach,$attach_name);
#ファイルロック開始
if( $lockkey ne "0" ){ &LOCK; }
if (!open(IN,"<:utf8","$linkdata_file")) { &ERROR( read_linkdata ); }
@BASE = <IN>;
close(IN);
foreach $data (@BASE) {
&LINKDATALIST;
if( $in{'editnum'} eq $CNTNUM ){
if( $in{'attach_file'} eq '' ){
if( $in{'CHDEL'} eq '1' ){
$in{'attach_file'} = ''; unlink("$updir/$IMAGE");
}else{
$in{'attach_file'} = $IMAGE;
}
}else{
unlink("$updir/$IMAGE");
$in{'attach_file'} =~ s/$updir\///g;
}
$in{'LINKNAME'} =~ s/\,/&%/g;
$in{'LINKURL'} =~ s/\,/&%/g;
$in{'LINKURL'} =~ s/&/\&/g;
$in{'COMMENT'} =~ s/\,/&%/g;
$in{'COMMENT'} =~ s/\<br \/\>/!%/g;
if( $in{'CLICK'} eq "" ){ $in{'CLICK'} = 0; }
$new_data = "$CNTNUM,$datenow,$DATE_LMT,$DATE_ESY,$in{'OPN'},$in{'NEWMARK'},$in{'CATEGORY'},$in{'LINKNAME'},$in{'HONORIFIC'},$in{'LINKURL'},$in{'COMMENT'},$in{'CLICK'},$in{'attach_file'},\n";
}else{
$new_data = "$CNTNUM,$DATE_LINKDATA,$DATE_LMT,$DATE_ESY,$OPN,$NEWMARK,$CATEGORY,$LINKNAME,$HONORIFIC,$LINKURL,$COMMENT,$CLICK,$IMAGE,\n";
}
push( @TOTAL,$new_data );
}
#実際にファイルに書き込む
if( !open(OUT,">$linkdata_file") ){ &ERROR( read_linkdata ); }
print OUT @TOTAL;
close (OUT);
#ファイルロック解除
if( $lockkey ne "0" ){ &UNLOCK; }
&SendFinish2;
}
No.4ベストアンサー
- 回答日時:
stdio::getFormDataに対しての見識がないので適切な回答はできませんが、以下を試すとどうなるでしょうか?
%in = ();
stdio::getFormData(\%in,1,"sjis",1,",","$updir/");
を、
use CGI;
%in = map decode_utf8($_), CGI->new->Vars;
に変更。
これで文字化けが解消する可能性はありますが、stdio::getFormDataに詳しい人が回答してくれるかもしれませんので、質問はオープンのままにされたほうがいいと思います。
この回答への補足
N60-BASIC様、Tacosan様、ryu_chan様、誠にありがとうございました。
各皆様のおかげで問題が解決ができまして、大変感謝しております。
今回は、ずばり直ったryu_chan様をベストアンサーとさせて頂きますので、どうぞご了承ください。
実は、もう1つだけ同じ文字化けの現象が起きていて、解決できない問題があります。(もう1つ質問を立てさせて頂ければと思います。
もし宜しければ、再度アドバイスを頂ければと思いますので、どうぞよろしくお願い致します。
ryu_chanさま
ご教示誠にありがとうございました!
ご指摘の通り、修正したところ、文字化け直りました!!!
m(_ _)m
感動しました!(^^)
まるで魔法のような感じ驚いています。
かれこれ3日間くらい格闘してきましたが、問題が解決できてスッキリしました。
誠にありがとうございました!感謝致します。
No.3
- 回答日時:
No.2のTacosanさんが言及されてますが、以下で解決できるかもしれません。
use Encode;
for my $value ( values %in ) {
$value = decode_utf8 $value;
}
この回答への補足
もしくは、別ファイルで行っている以下のデコード処理が問題なのでしょうか?
※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;
}
}
ryu_chanさま
ご回答ありがとうございました。
上記コードも試しましたが、文字化けは解消されませんでした(>_<)。
冒頭で以下のような宣言をしていますが、これが問題になっているのでしょうか?
#-------------------------------------------------
# 受け取ったデータの変換
#-------------------------------------------------
%in = ();
stdio::getFormData(\%in,1,"sjis",1,",","$updir/");
No.1
- 回答日時:
惜しいところまで行ってますね。
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/12 …
ご参考まで。
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
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- その他(プログラミング・Web制作) python flask から fastapiへの移行時のエラー対処 1 2023/02/05 12:26
- その他(プログラミング・Web制作) python 2 2022/12/23 09:06
- Visual Basic(VBA) このVBAでExcelアプリケーションを作成は必要ですか? 3 2023/07/19 21:13
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- その他(プログラミング・Web制作) Python - Excel で Webからデータを連続取得したいのですが エラーが出ます 1 2023/07/06 20:08
- その他(プログラミング・Web制作) Pythonを勉強しています。 5 2023/08/25 09:51
- その他(プログラミング・Web制作) ColabでのPytorchのエラー 1 2022/11/19 20:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlをwindows環境でshift-jis...
-
[perl5.8] SJISで出力したはず...
-
複数種類の括弧でくくられてな...
-
Data::Dumper;でダンプ後表示し...
-
HTTP::Request::Common qw(POST...
-
VBAでCSVファイルの特定行を書...
-
VBAでCSVファイルを途中行まで...
-
batファイルでrenameができませ...
-
ExcelをCSV書き出す場合のシー...
-
awkスクリプトでダブルクォーテ...
-
DOSコマンドで、標準出力を出力...
-
Firefox で file:// で始まる U...
-
ファイル出力の改行コードをLFに
-
Perlの変数に文字数制限(容量...
-
fopenでディレクトリ内の全ファ...
-
[Perl]ファイル出力のエンコー...
-
同じようなソースなのですが片...
-
エクセルVBA コードが同じでも...
-
巨大なテキストの最終行を取得...
-
エクセルVBAで素数だけを出力す...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
perlをwindows環境でshift-jis...
-
Perl cgiの文字化けを直したい ...
-
perlでuse utf8でsjisのファイ...
-
HTTP::Request::Common qw(POST...
-
消費税の計算で 税込価格から...
-
does not map to shiftjis は解...
-
Perl:Unicodeプロパティ作れない
-
Perlでのファイル出力における...
-
Perl utf8上でshiftjisをデコード
-
複数種類の括弧でくくられてな...
-
Data::Dumper;でダンプ後表示し...
-
utf-8での日本語正規表現の書き方
-
[Perl]Shift-JISのXMLを解析する場
-
ファイル出力をUTF8Nではなくて...
-
perl5.8.3のunicode環境で日本...
-
perlで新規ファイルを作成でき...
-
perlでのtext読み込み
-
[perl5.8] SJISから読み込んだ~と
-
Perl 正規表現について
-
Perlを用いて、XMLファイルの中...
おすすめ情報