2009-12-2[水] Unicodeコンソール関係の適当メモunix/linux系なら、過去互換気にしなければ普通utf8環境. winだと一応(たぶんnt系. 少なくともw2k以降の) dos窓にて chcp 65001 とすれば、文字エンコードをutf8にした環境に (あるいは chcp 65000 とすれば utf7環境に) はなる.
ただし、文字フォントが日本語ファイル未対応なので、そのままだと文字化けする.
こちらのサイト等みて
レジストリ設定すれば日本語表示可能になる.
で表示はなんとかなるが、問題は、日本語入力(IME)が使えない. 日本語環境とみなされていないよう. CP932でのみ判定してるのか、DOS標準コマンドのヘルプが英語になる. (当然sjis依存ツールは文字化けなんで、それに比べれば十分マシだけど). os標準の入力(MS-IME)が出来れば、もっとutf8コンソール普及するかも? (Win7は未確認だけどたぶん)
utf8環境での、言語(国)の判定は win32apiだと LCID GetUserDefaultLCID(); で判定可能。LCIDでの日本は1041. (他にも何か判定方法はあったような気はするけど、これが楽かも.
C標準ライブラリの場合 setlocaleはあれど getlocale なんてのはないので標準的な判定はなし.
(そもそもsetlocaleの引数/戻値はosによって設定する値が違うので、移植性を考えよう無い)
unix系だと環境変数LANG みれば... iconv とか gettext とか用いるが普通?
オーソドックスなコンパイラなら、ソース中のマルチバイト文字(というかSJIS)対応をするオプションを立てずにutf8でソース書けばok (のはず).
winでsjisコンソールのままプログラム内部の処理をutf8にした場合 問題になるのは
あたりか. もちろん通常プログラムが扱うテキストファイルはutf8でいいとして. このためにCランタイムやライブラリを修正するとしたら、 コマンドライン引数はW系文字列で取得してutf8化すればすむだろうが、 対コンソール入出力についてはどうする? 標準入出力関係だけならば、fileno(fp) が 0,1,2 なら標準入出力エラー出力だろうで、 決めうち変換する? (freopenとかやられると不味いそう?) win系コンパイラ(vc,mingw,dm,bcc,watcom)ならio.hにfileno(),_get_osfhandle()があるだろうで、 FILE fp = stdout; //fopen("hoge","rb"); int fno = fileno(fp); HANDLE hFile = _get_osfhandle(fno); DWORD type = GetFileType(hFile); として type == FILE_TYPE_CHAR ならコンソールだろうとして、扱えばいいか (LPTは微妙) コンソールのコードページ判定は GetConsoleCP(); // コンソール入力のコードページ GetConsoleOutputCP(); // コンソール出力のコードページ でできそうなので、utf8(65001)以外ならその文字エンコードに変換してから出力すれば... FILE関係, io.hな_open関係 にごっそり手を入れる必要があるのでやってられないけど(可能性としては).
utf8化することでSJISに対し
が、SJIS(DBC)だと基本的に 1バイト文字は半角、2バイト文字は全角、になるので
固定フォントによるテキスト表示をバイト数で桁あわせできて楽だったのが、utf8だと、単純にできなくなる.
ただ日本語フォントかつ SJIS範囲の文字のみを前提に決め内するならば,
で扱うのでもいいかも. 欧州系の文字の場合半角扱いのフォントのほうが多いだろうけど、 JIS第一水準のギリシア・ロシア文字あたりは、日本系のフォントなら全角だったりして、その判定は 結局フォント別に判定が必要になってくるかも...なので、あくまでJIS漢字の範囲を前提にするならばこの程度でよいかも、と.
vcの場合fopen("hoge", "rb,ccs=UTF8")やopen("hoge", _O_RDONLY|_O_UTF8); のようにオープン時にutf8(同様にutf16)指定することが可能なよう.
D言語環境とか、mingwでの文字列をutf8ベースにする場合とかを考えてた. mingwの場合、msvcrt.dll系のdllを使うので、ライブラリ関数一部差替は ヘッダ弄ってimportやめてリンクする形できるだろうが... あるいは newlib 使ったバージョンとかはないのだろうか... とか何かと大事な作業に化けてしまうので、思うだけで終わってしまったのでした. |