WideStudio Programming (2-2)~文字コード変換が必要な場合

画面への文字列の出力に関してはWideStudio/MWTが自動的にやってくれるのであまり考える必要はありませんが、外部環境とのやりとりでコード変換が必要な場面は他にもあります。主に下記の2箇所です。

・ファイル操作(open/remove/rename等)を行なう場合
・Windows APIを呼び出す場合

対応の手順としては、

a) shift-jisに変換して1byte系のライブラリ関数/API関数を呼ぶ、
b) 関数のインターフェースでutf-8文字コードを選択することが出来る場合(Visual Studioのfopen等)は、それを使う
c) utf-16leに変換して2byte系のライブラリ関数(_wfopen等)/API関数(CreateFileW等)を呼ぶ

の三通りが考えられます。

aは汎用性に欠けます。というのは、unicodeからshift-jisへは変換出来ない文字がありますし、unicodeからshift-jis(CP932)への変換ルール自体がおかしいという説もあって、あまりお勧めではありません。実際、ファイル名にshift-jisに無い文字を使われていたら、aのやり方ではfopen出来ません。まあ、今どきshift-jisじゃないよね、という話です。

bは一番楽ですが使っているコンパイラ等の処理系に依存しますのでとりあえず除外します。

Windows環境で最も確実なのはcの、utf-16leに変換して2byte系のライブラリ関数/APIを呼び出すというやり方です。

というわけで、Windows APIの呼び出しには~W系のものを使い、基本的なファイル操作については、タンゴレンではそれぞれ _wfopen/_wrename/_wremove  等のwchar_t向けのライブラリ関数を(もちろんラッパー関数を作って)使っています。

が、ここでやっかいなのが、fstream です。

なんかそれっぽい wfstream というのが標準ライブラリにあるのですが、これは取り扱う文字がwchar_tになっているだけで、ファイル名に関してはchar文字列でしか指定できないっぽいです。少なくとも標準の範囲では。Microsoftのサイトの資料を見るとfstreamのopenの引数にwchar_t*が渡せるものが出てるんですけれども、他所ではそういうのは載ってませんし、開発に使ってるMinGWではそれを使おうとするとコンパイルエラーになります。つまり、サポートされていません。

_wfopenを使ってFILE*を取得して後はstdioで入出力しても良いのですが、紆余曲折ありまして、タンゴレンではそういうことが出来るfstreamもどきのクラスを作ってみました。(クラスの概略は次の記事にて)