文字コード変換 †コード †ワイド文字列をマルチバイト文字列に変換 †int WideCharToMultiByte( UINT CodePage, // コードページ DWORD dwFlags, // 処理速度とマッピング方法を決定するフラグ LPCWSTR lpWideCharStr, // ワイド文字列のアドレス int cchWideChar, // ワイド文字列の文字数 LPSTR lpMultiByteStr, // 新しい文字列を受け取るバッファのアドレス int cchMultiByte, // 新しい文字列を受け取るバッファのサイズ LPCSTR lpDefaultChar, // マップできない文字の既定値のアドレス LPBOOL lpUsedDefaultChar // 既定の文字を使ったときにセットするフラグのアドレス ); ex.) wchar_t sText = L"いろはに"; char sDest [256]; DWORD dwLen = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)sText, -1, NULL, 0, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)sText, -1, sDest, dwLen, NULL, NULL); sDest[dwLen] = '\0'; CodePage?がCP_UTF7、CP_UTF8の場合、lpDefaultChar?とlpUsedDefaultChar?はNULL(0)でなければならないらしい。 ちなみに、wcstombs() は、内部で WideCharToMultiByte?() を呼び出している。 ex.) int mbs_len = wcstombs( NULL, msg, 0 ); char * mbs = new char [mbs_len + 1]; try { wcstombs( mbs, msg, mbs_len + 1 ); } catch (...) { } delete mbs; マルチバイト文字列をワイド文字列に変換 †int MultiByteToWideChar( UINT CodePage, // コードページ DWORD dwFlags, // 文字の種類を指定するフラグ LPCSTR lpMultiByteStr, // マップ元文字列のアドレス int cchMultiByte, // マップ元文字列のバイト数 LPWSTR lpWideCharStr, // マップ先ワイド文字列を入れるバッファのアドレス int cchWideChar // バッファのサイズ ); ex.) char sText = "いろはに"; wchar_t sDest [256]; DWORD dwLen = MultiByteToWideChar( CP_ACP, 0, sText, -1, NULL, 0); MultiByteToWideChar( CP_ACP, 0, sText, -1, sDest, dwLen); sDest[dwLen] = '\0'; mbstowcs() は、内部で MultiByteToWideChar?() を呼び出している。 メモ †Unicode †ひとことで Unicode といってもいろんな文字セットがある。 とりあえず、Wikipedia の説明 。 おそらく一番よく使われるのが UTF-8 だが、UTF-8 は 0x00 〜 0x7F までは ASCIIコードと全く同じ(つまり、Shift-JIS とも同じ)。それより大きな値については UTF-16 と同じ 2byte 以上のコードとなる。 ちなみに、UTF-16 と UTF-32 には、先頭 2byte に BOM(Byte Order Mark) というモノがついてくることがある。ここには、その文字コードが LE(little endian/FFFE) なのか BE(big endian/FEFF) なのかを区別するための情報が書き込まれる。 ところで、本来 BOM が必要ない(LE/BE の区別がない)はずの UTF-8 にも BOM がつくことがある。私は、その文字コードが UTF-8 であるかどうかを識別するためだけに使うものと解釈してるんだけど、ちとよく解ってない。 C++ 環境依存 †wchar_t という型は「ワイド文字」と呼ばれるが、これは環境によって実装がことなる模様。 VC++ (Win32 環境?) UTF-16 には BE(big endian) と LE(little endian) の2種類があるが、 Windows 環境 (LE) の ワイド文字がなぜ UTF-16BEなのかは謎。 gcc (大抵の unix 環境) VC++ の罠 †VC++ では、コンパイラの設定によって、 デフォルトでマルチバイト文字セットを使うか、 Unicode を使うか、という設定がある。 VC++.NET 2003 なら、プロジェクトのプロパティの[構成プロパティ]の[全般]の[文字セット] 。 _T というマクロは、文字列を環境デフォルトに変換するマクロ。 _T("あいうえお"); マルチバイトをデフォルトにしているが、ワイド文字列として扱いたい場合は、 L"あいうえお" とする。 文字列は必ず †文字列を、バイト配列や vector で扱うときは、 null(0) 終端すると確実。 char str [16]; ... str [15] = '\0'; std::vector<char> str; ... str.push_back( 0 ); C/C++ の文字列のお約束。 |