ソフトウェア開発 Win32プログラミング

UnicodeをUTF-8に変換する

戻る


文字コードのUnicodeをUTF-8に変換する方法を以下に示す。

#include <windows.h>

INT cch;
WCHAR szUTF8[1024];
cch = WideCharToMultiByte(CP_UTF8, 0, szWide, -1, szUTF8, 1024, NULL, NULL);
szUTF8[cch] = 0;

しかし、この方法は、Windows 98/Me/NT 4.0 以降でなければ使えない。

Windows 95でも変換できるようにするには、次のようにするとよい。

#include <windows.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;

LPSTR APIENTRY ConvertUnicodeToUTF8(LPCWSTR pszWide, INT cch, BOOL fCESU8)
{
    INT i, c;
    LPSTR pszUTF8;
    BYTE *pb;
    UINT wch;

    c = 0;
    for(i = 0; i < cch; i++)
    {
        if (pszWide[i] <= 0x007F)
            c += 1;
        else if (0x0080 <= pszWide[i] && pszWide[i] <= 0x07FF)
            c += 2;
        else if (0x0800 <= pszWide[i])
        {
            if (!fCESU8 && i + 1 < cch &&
                0xD800 <= pszWide[i] && pszWide[i] <= 0xDBFF &&
                0xDC00 <= pszWide[i + 1] && pszWide[i + 1] <= 0xDFFF)
            {
                c += 4;
                i++;
            }
            else
                c += 3;
        }
    }

    pszUTF8 = new CHAR[c + 1];
    c = 0;
    for(i = 0; i < cch; i++)
    {
        pb = (BYTE *)&pszWide[i];
        if (pszWide[i] <= 0x007F)
        {
            pszUTF8[c] = pb[0];
            c++;
        }
        else if (0x0080 <= pszWide[i] && pszWide[i] <= 0x07FF)
        {
            pszUTF8[c] = (BYTE)(((pb[0] & 0xC0) >> 6) | 
                                ((pb[1] & 0x07) << 2) | 0xC0);
            pszUTF8[c + 1] = (BYTE)((pb[0] & 0x3F) | 0x80);
            c++;
            c++;
        }
        else if (0x0800 <= pszWide[i])
        {
            if (!fCESU8 && i + 1 < cch &&
                0xD800 <= pszWide[i] && pszWide[i] <= 0xDBFF &&
                0xDC00 <= pszWide[i + 1] && pszWide[i + 1] <= 0xDFFF)
            {
                wch = (pszWide[i] - 0xD800) * 0x400 + 
                      (pszWide[i + 1] - 0xDC00) + 0x10000;
                pszUTF8[c] =     (BYTE)(((wch & 0x001C0000) >> 18) | 0xF0);
                pszUTF8[c + 1] = (BYTE)(((wch & 0x0003F000) >> 12) | 0x80);
                pszUTF8[c + 2] = (BYTE)(((wch & 0x00000FC0) >> 6) | 0x80);
                pszUTF8[c + 3] = (BYTE)( (wch & 0x0000003F) | 0x80);
                c += 4;
                i++;
            }
            else
            {
                pszUTF8[c] = (BYTE)(((pb[1] & 0xF0) >> 4) | 0xE0);
                pszUTF8[c + 1] = (BYTE)(((pb[0] & 0xC0) >> 6) | 
                                        ((pb[1] & 0x0F) << 2) | 0x80);
                pszUTF8[c + 2] = (BYTE)((pb[0] & 0x3F) | 0x80);
                c += 3;
            }
        }
    }
    pszUTF8[c] = 0;
    return pszUTF8;
}

int main(void)
{
    LPSTR pszUTF8;
    INT cch;
    FILE *fp;
    static const WCHAR szWide[] = L"テストです。ABCABC123あいうえお漢字";

    cch = wcslen(szWide);
    pszUTF8 = ConvertUnicodeToUTF8(szWide, cch, FALSE);
    fp = fopen("utf8.txt", "w");
    fprintf(fp, "\xEF\xBB\xBF");
    fprintf(fp, "%s", pszUTF8);
    fclose(fp);
    delete[] pszUTF8;
    return 0;
}

ソース: wideutf8.zip


戻る

©片山博文MZ
katayama.hirofumi.mz@gmail.com

inserted by FC2 system