(前回の続き)
Perl で ANSI コードページを知りたい
Win32 モジュールを使う
Win32 モジュールは Win32 API の(比較的)単純なラッパーである関数群を提供するもの。
use strict; use Win32; # ANSI コードページ print("ANSI cp = ", Win32::GetACP(), "\n"); # OEM コードページ print("OEM cp = ", Win32::GetOEMCP(), "\n"); # コンソール入力コードページ print("console input cp = ", Win32::GetConsoleCP(), "\n"); # コンソール出力コードページ print("console output cp = ", Win32::GetConsoleOutputCP(), "\n");
日本語版 Windows だと結果は全部「932」になる。
ANSI cp = 932 OEM cp = 932 console input cp = 932 console output cp = 932
エラー対策を考慮すると以下のようになる。
use strict; ## ansi_codepage() # ANSIコードページの値を返す。失敗時およびWindowsでない場合は # undefを返す。 sub ansi_codepage() { my ($ret); # Windowsでないならundef ($^O eq 'MSWin32') or return $ret; eval { # Win32モジュールは無いかもしれない require Win32; $ret = Win32::GetACP(); }; # 前のevalの成功時のみ値が返る return $ret; } print("ANSI cp = ", ansi_codepage(), "\n");
ANSI cp = 932
Encode::Locale モジュールを使う
use strict; use Encode::Locale; # 現在のロケールの文字コード # WindowsではANSIコードページの文字コード(固定らしい) print($Encode::Locale::ENCODING_LOCALE, "\n"); # コンソール入力コードページの文字コード # Windows以外では ENCODING_LOCALE と同じになるらしい print($Encode::Locale::ENCODING_CONSOLE_IN, "\n"); # コンソール出漁コードページの文字コード # Windows以外では ENCODING_LOCALE と同じになるらしい print($Encode::Locale::ENCODING_CONSOLE_OUT, "\n");
日本語版 Windows での実行結果は以下の通り。
cp932 cp932 cp932
Encode::Locale は Windows 専用ではない。(UTF-8 運用の)Linux では以下のような結果が得られる。
UTF-8 UTF-8 UTF-8
なお、Encode::Locale の主たる目的は、「Encode モジュールで使う文字コードに 'locale'
を指定することで先述の ENCODING_LOCALE
が使われるようにする」ことである。すなわち、前回に挙げたような、非 ASCII のファイル名を扱いたい場合には、このモジュールを読み込んで 'locale'
指定を使うと環境費依存で所望の処理が行える。
# 文字コードはUTF-8 use strict; use utf8; use Encode qw(encode); use Encode::Locale; my $f = 'アレ.txt'; # Unicode文字列 # 文字コード名を 'locale' にすると、ENCODING_LOCALE による # バイト列に変換される open(my $h, '>', encode('locale', $f)) or die; print $h ("TeX\n"); close($h);
Lua で ANSI コードページを知りたい
Lua の場合、標準 C 関数の setlocale()
の単純なラッパーである os.setlocale()
という標準ライブラリ関数が用意されているので、これを利用して ANSI コードページを取得できる。
--- ansi_codepage() -- ANSIコードページの値を返す. -- @returns ANSIコードページの値(失敗=nil) function ansi_codepage() local ok, ret = pcall(function() -- setlocale(LC_CTYPE, NULL) と同じ. -- 現在のロケールの値の文字列を返す. local org = assert(os.setlocale(nil, "ctype")) -- Windowsにおいて, 既定のロケールを設定し, そのときに特に -- ANSIコードページを指定する. 戻り値は実際のロケールの値 -- で, Windowsの場合 "言語_地域.コードページ" という形式の -- 文字列になる. -- Windows以外では ".ACP" というロケール名は無効であるため, -- nilを返し, assertがエラーを発する. local ret = assert(os.setlocale(".ACP", "ctype")) -- 一度変更したロケールを元に戻す. assert(os.setlocale(org, "ctype")) -- 先述の文字列の中のコードページの数字列を抽出し, 数値に変換 -- したものを返す. 形式不正ならエラーになる. return assert(tonumber(ret:match("^.*%.(%d+)$"))) end) -- 失敗ならnil, 成功ならret return (ok or nil) and ret end print(("ANSI cp = %s"):format(ansi_codepage()))
日本語版 Windows での実行結果は以下の通り。
ANSI cp = 932