ルモーリン
ホーム更新サービス雑談ランドナーコースガイド鉄ゲタ自転車Linuxリンク連絡先

文字化けの予防

背景

自作プログラムでcp932にない文字をコマンドプロンプトに表示しようとしたり(ハングアップの可能性)、 ファイル名に含めようとする(動作しない)ので回避したい。

ポイント

cp932にない文字をアンダースコア「_」に変換して、とりあえず動作すりゃいいやという方針で行きます。 Encode::encodeの第三パラメタを利用します。 ここにサブルーチンのリファレンスを指定しておくと、変換できない文字をサブルーチンに渡してくれるので、代用の文字を返します。
ここを見ました。
「coderef for CHECK」
Encode - character encodings in Perl - metacpan.org
$ascii = encode("ascii", $utf8, sub{ sprintf "<U+%04X>", shift });

コード

リテラルの「\x{2661}」は「♡(♡)」です。 このホームページやコードの編集をVimで行っている都合でハートマークを直接入力できず、文字コードを指定しています。
#!/usr/bin/env perl -w

use utf8;
use strict;
use warnings;

use Encode::Argv;
use Encode::Locale;

use open IO => ":utf8";

binmode STDIN, ":encoding(console_in)";
binmode STDOUT, ":encoding(console_out)";

$| = 1;

my $msg = "上坂すみれの\x{2661}をつければかわいかろう";
print "$msg\n";

my $msg_check = Encode::decode locale => Encode::encode locale => $msg, sub {return "_";};
print "$msg_check\n";

実行結果

Windowsの場合はコマンドプロンプトがcp932(シフトJISの親戚)なので変換できません。 その場合に警告が表示されます。 2行目は変換できない文字の代わりをアンダースコア「_」にしているので警告が出ません。
"\x{2661}" does not map to cp932 at sample_52.pl line 18.
上坂すみれの\x{2661}をつければかわいかろう
上坂すみれの_をつければかわいかろう
Linuxの場合はコンソールがutf-8なので、そのまま表示でき…あれ? すみません、使っているTeraTermがMBCSだそうで結局表示できないや、しくしく…。 とりあえずttyのトコまではutf8で出力されているようです(ホントかな?)。
上坂すみれの?をつければかわいかろう
上坂すみれの?をつければかわいかろう