dポイントプレゼントキャンペーン実施中!

use utf8;
binmode STDOUT, ':utf8';
binmode STDIN, ':utf8';
use strict;
use Encode;

sub main(){
#UTF-8(BOMなし),CRLFのファイルに書いてます。
my $str = "あ";
my $bin = $str;
$bin = Encode::encode('euc-jp', Encode::decode('utf8', $str));
$bin = Encode::encode('utf8', Encode::decode('euc-jp', $bin));

print "Content-Type:text/plain;charset=UTF-8\n";
print "\n";
print $bin;

}

&main;

=======================
希望する出力結果:

============================
結果:Internal Server Error
Apacheのエラーログ:
[Wed Jan 09 15:07:34 2008] [error] [client 127.0.0.1] Premature end of script headers: 20080109-1.pl
[Wed Jan 09 15:07:34 2008] [error] [client 127.0.0.1] at C:/Environment/Perl/v5.8.8/lib/Encode.pm line 166.\r
=========================
質問:
どのように修正すればよいか?

A 回答 (2件)

2行目3行目の binmode はいらないんじゃないでしょうか?


それはそれぞれ、内部 UTF8(UTFフラグ付き文字列)をそのまま出力(入力)する時に使用するもののようです。

ですから、binmode を使用する場合、内部UTF8文字列をそのまま print 文に渡してやって
binmode STDOUT, ':utf8';
my $bin = "あ";
print $bin;
で正常表示。

binmode を使用しない場合、内部文字列をいったんUTFフラグを削除して(通常の UTF8 にエンコーディングして)
my $bin = "あ";
$bin = Encode::encode('utf8', $bin );
print $bin;
で正常表示となるはずです。

この回答への補足

>2行目3行目の binmode はいらないんじゃないでしょうか?

いけね,文献読んだのに間違えた。

>When you encode, the resulting UTF8 flag is always off.
>When you decode, the resulting UTF8 flag is on unless you can unambiguously represent data. Here is the definition of dis-ambiguity.

逆だと思い込んでた。
==============
・・・けど,2行目と3行目削っても同じエラーが出るんですよ。

Windows XP SP3 RC1(v3264)
Apache 2.2.6
Perl 5.8.8
============
あれ?さっき,成功したと思ったんだけど
Prematureどーたらがこれだけでも出るようになっている。
少しちょっと頭冷やしてこよう。

use utf8;
use strict;
use Encode;
binmode STDOUT, ':utf8';
binmode STDIN, ':utf8';

sub main(){
#UTF-8(BOMなし),CRLF
my $str = "あ";
print $str;

}

&main;

補足日時:2008/01/09 19:08
    • good
    • 0
この回答へのお礼

後者が成功しないのは,Content-Type:text/plainを吐いてないのに
CGIを利用としたからのようです。

相変わらず取り払ってもエラーが消えず。

お礼日時:2008/01/09 20:31

>相変わらず取り払ってもエラーが消えず。



#1の補足にあるスクリプトで試してみましたが、こちらではエラーになりません。
スクリプトは utf-8で保存しています。

binmode をしないと

Wide character in print at mmm.pl line 10.

という警告が出ますが。

この回答への補足

#1のお礼に書いたとおり,
=============================================
コマンドプロンプトではなくCGI経由で利用していて,
【#1の補足のソースは】
print "Content-Type:text/plain\n\n";
を追加することで,エラーは発生しなくなっています。

尤も大元の質問は
print "Content-Type:text/plain;charset=UTF-8\n";
print "\n";
を何となく
print "Content-Type:text/plain;charset=UTF-8\n\n";
にしたという違いはあれど,
2行目,3行目のbinmodeを取り除いても「あ」が表示されておらず、エラーが出ております。
=====================================

補足日時:2008/01/10 01:24
    • good
    • 0
この回答へのお礼

use utf8;
use strict;
use Encode;

#一応「あ」が表示された。
#元々今回の実験は ある文字列を
#UTF-8の文字列をEUC-JPにして
#もう一回UTF-8にして元通りか比較する,というものだった。

##元々PHPの別な検証だった。
##PHPでは,mb_convert_encodingで指定した変換先の
##文字集合に含まれない文字は?に置換されるが,
##これがイヤで。変換できない時は「例外」として「キャッチしたかった」んだ。

##なので EUC-JPに含まれない文字列を
##リテラルで指定し,UTF-8で戻ってきたときの
##文字列を元の文字列と比較することで,
##エラーを検知しようとしていた。

###unicode.from_error_mode = U_INVALID_STOPって何のために在るんだろう?

##ただし,Encode::encode関数の仕様によるとperlでは変換できないときundefを返すようなので比較は必要ない

sub main(){
#UTF-8(BOMなし),CRLFのファイルに書いてます。
my $str = "あ";

#$binに代入していたことには特に意味はない。
#強いて言えばPHPで検証をしていたときの名残。

#うまくいかなかった理由としては
#http://www.perlmonks.org/?node_id=569561
#らしいが,俺は良くは理解できてない。

#このサイト自体は見つけていたが,簡単に読める気しなかったので読まずにスルーしていた。

#締め切るまで一日くらい置くつもりだから
#よくわかる解説をしてくれるなり,
#(sequence of bytesに変換したらうまく通ることがわかるようなテストケースとか)
#何かいいたいことがあるなら言うなり,好きにしてくれ。

#今回はポイントが#1さんに10ptだけで終わるかも。ごめんね。

my $bin;

#一応「あ」が表示された。
#以下の一行が違う
$bin = Encode::encode('euc-jp',$str);
$bin = Encode::encode('UTF-8', Encode::decode('euc-jp', $bin));

print "Content-Type:text/plain;charset=UTF-8\n\n";
print $bin;

}

&main();

お礼日時:2008/01/10 02:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!