iRSSの日記 このページをアンテナに追加 RSSフィード

2007-07-11

[][] Wide character in print at ...

この「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);


Wide character in print at ...

まとめ

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));

Encode - Walrus, Digit.