この「Wide character in print at ...」には、何度も、悩まされては、
理解するのだが、のど下過ぎると、わすれちゃう。
再復習。
printするときに、utfフラグがついているのがいかんです。
Wide character in print at ..のメッセージがでる原因は,print対象の文字列にutf8フラグがついているということ
#!/usr/bin/perl -w
use strict;
use warnings;
use utf8;
my $str = 'あああ';
print $str;
↑これを実行すると
Wide character in print at ... line 6.
なんてメッセージがでます。
対策としては
#!/usr/bin/perl -w
use strict;
use warnings;
use utf8;
my $str = 'あああ';
utf8::encode($str);
print $str;
$strについた,utf8フラグをこれで明示的に落とせる。
こうするか
#!/usr/bin/perl -w
use strict;
use warnings;
my $str = 'あああ';
print $str;
use utf8;を最初からつけない。
これで、'あああ'はutf8文字列はみなされなくなる。
use utf8をつけないということでいいかと思うのですが
eucをutf8に変換したりするときに、このフラグがついたりするのです。
これが、やっかいで、わすれがち。
printするまえとか、encodeした直後に、フラグをはずしてあげればOKそう。
#!/usr/bin/perl -w
use strict;
use warnings;
use Encoding;
use utf8;
my $str = 'あああ';
$str = Encode::encode('utf-8',$str);
print $str;
↑こうすると、フラグをはずすことができ、Wide character in print at ...はでない
#!/usr/bin/perl -w
use strict;
use warnings;
use Encoding;
#use utf8;
my $str = 'あああ';
$str = Encode::encode('utf-8',$str);
print $str;
しかし↑このように、$strにutfフラグがついていないのに、Encode::encode('utf-8',$str);をしてしまうと、出力結果は文字化けてしまう。フラグがあるときのみEncode::encode('utf-8',$str);すべし。
#!/usr/bin/perl -w
use strict;
use warnings;
use Encoding;
#use utf8;
my $str = 'あああ';
$str = Encode::encode('utf-8',$str) if utf8::is_utf8($str);
print $str;
これでOK。
utf8::is_utf8では実際の文字列がUTF-8かどうかではなく、あくまでフラグがついているかどうかを確認します。そのため、UTF-8の文字列もフラグが付いていなければ上記の出力はno flagとなります。またutf8::is_utf8はuseしなくても使用できる。useすると全然違う意味あいになるので注意。
UTF-8フラグが付いていたら、encodeを使用してフラグをはずします。以下の例では$stringをutf-8に変換して出力します。
print encode('utf-8', $string);
まとめ
printする前に、文字列にutfフラグをはずしておきましょう。
$str = Encode::encode('utf-8',$str) if utf8::is_utf8($str);
print $str;
こんな感じにしておけば、OK
こんな曲者にも注意
decode と from_to 同じようだが、utf8フラグのたつたたないが、異なる。
警告: 次の呼び出しは全く同じに見えますが、完全に等しくはありません。
from_to($data, "iso-8859-1", "utf8"); #1
$data = decode("iso-8859-1", $data); #2#1 と #2 の両方は完全に有効なUTF-8文字列を $data に設定します。しかし、 #2 だけがutf8フラグをつけます。 #1 と等価な呼び出しは以下のようなものです。
$data = encode("utf8", decode("iso-8859-1", $data));