MFCの基礎 - UTF-8

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

wchar_tはUTF-16に対応しており、Shift-JIS等からUTF-8に直接的で変換できない。
ここでは、様々な文字コードからUTF-8へ変換する方法を記載する。


サンプルコード

 #include <windows.h>
 
 char *pstrShiftJIS = "文字列のテスト";
 wchar_t pstrUTF16[512] = {\0};
 char *pstrUTF8[512]    = {\0};
 
 // Shift-JISからUTF-16へ変換
 ::MultiByteToWideChar(CP_ACP, 0, pstrShiftJIS, -1, pstrUTF16, 512);
 
 // UTF-16からUTF-8へ変換
 ::WideCharToMultiByte(CP_UTF8, 0, pstrUTF8, -1, pstrUTF16, 512, NULL, NULL);


以下の例では、UTF-8への変換を関数として定義している。

 void ShiftJISToUTF8(char pstrShiftJIS[])
 {
    wchar_t pstrUTF16[512] = {\0};
    char pstrUTF8[512]     = {\0};
 
    // UTF-16へ変換する前に、文字列を代入するバッファのサイズを確認する
    int iLengthUTF16 = ::MultiByteToWideChar(CP_ACP, 0, pstrShiftJIS, lstrlen(pstrShiftJIS) + 1, NULL, 0);
    if(iLengthUTF16 <= sizeof(pstrUTF16) / sizeof(pstrUTF16[0]))
    {
        // まず、UTF-16へ変換する
        ::MultiByteToWideChar(CP_ACP, 0, pstrShiftJIS, lstrlen(pstrShiftJIS) + 1, pstrUTF16, MAX_PATH);
 
        // UTF-8へ変換する前に、文字列を代入するバッファのサイズを確認する
        int iLengthUtf8 = ::WideCharToMultiByte(CP_UTF8, 0, pstrUTF16, iLengthUTF16, NULL, 0, NULL, NULL);
        if(iLengthUtf8 <= sizeof(pstrUTF8))
        {
            // 次に、UTF-16からUTF-8へ変換する
            ::WideCharToMultiByte(CP_UTF8, 0, pstrUTF16, iLengthUTF16, pstrUTF8, sizeof(pstrUTF8), NULL, NULL);
        }
    }
 }


以下の例では、UTF-8からShift-JISへの変換を関数として定義している。

 void UTF8ToShiftJis(char pstrUTF8[])
 {
    wchar_t pstrUTF16[512] = {\0};
    char pstrShiftJIS[512] = {\0};
 
    // UTF-16へ変換する前に、文字列を代入するバッファのサイズを確認する
    int iLengthUTF16 = ::MultiByteToWideChar(CP_UTF8, 0, pstrUTF8, lstrlen(pstrUTF8) + 1, NULL, 0);
    if(iLengthUTF16 <= sizeof(pstrUTF16) / sizeof(pstrUTF16[0]))
    {
       // まず、UTF-16へ変換する
       ::MultiByteToWideChar(CP_UTF8, 0, pstrUTF8, lstrlen(pstrUTF8) + 1, pstrUTF16, MAX_PATH);
 
       // Shift-JISへ変換する前に、文字列を代入するバッファのサイズを確認する
       int iLengthShiftJIS = ::WideCharToMultiByte(CP_ACP, 0, pstrUTF16, iLengthUTF16, NULL, 0, NULL, NULL);
       if(iLengthShiftJIS <= sizeof(pstrShiftJIS))
       {
          // 次に、UTF-16からShift-JISへ変換する
          ::WideCharToMultiByte(CP_ACP, 0, pstrUTF16, iLengthUTF16, pstrShiftJIS, sizeof(pstrShiftJIS), NULL, NULL);
       }
    }
}



UTF-8のBOM

UTF-8では、ファイルの先頭にUTF-8であることを示す3バイトのデータ0xEF、0xBB、0xBFが付加されている。
これを、BOMと呼ぶ。

UTF-8のファイルを出力する場合、以下のように出力しないと、UTF-8として正しく認識されない。
(BOMが付加されていないUTF-8を、UTF-8Nという)

 buf2[0] = 0xEF;
 buf2[1] = 0xBB;
 buf2[2] = 0xBF;
 buf2[3] = nullptr;