UTF-8 to UTF-16 example1
更新日2007年01月18日

UTF-8 to UTF-16 example1
UTF-8 to UTF-16 への文字コード変換のサンプル実装。(Windows APIを使用)
MinGW + gcc 環境において動作確認してあります。

Example Code
以下の例は、Utf8ToUtf16()の実装の例です。 [utf8_to_utf16_1.zip]
/*
 * file:Utf8ToUtf16_1.c
 */
/** @file
 * @brief UTF-8 → UTF-16 への変換実装サンプルプログラム。
 * 
 * UTF-8 → UTF-16 への変換実装サンプルプログラム。(Windows APIを使用)
 * UTF-8にて用意された"data.txt"ファイルを読み込み、
 * UTF-16へと変換、
 * "out.txt"ファイルへと出力します。
 * ファイルへ出力時には、ファイルの頭に2バイトのデータ
 * 0xff 0xfe を出力します。
 */
#define STRICT
long min(long a, long b)
{
    long c;
    c = (a < b)?(a):(b);
    return c;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define DEFAULT_BUFF_LEN 512

int Utf8ToUtf16(wchar_t *dest, size_t dest_size, char *src, size_t src_size);

int main(int argc, char *argv[])
{
    char    instr[DEFAULT_BUFF_LEN];
    wchar_t outstr[DEFAULT_BUFF_LEN];
    wchar_t bom;
    char    outbuffbom[4];
    FILE    *pFile;
    long    sizeFile;
    size_t  countRead;
    int     iResult = 0;
    int     instr_size = 0;
    
    /*
     * ファイルより文字列を読み込み
     */
    memset(instr, 0, sizeof(instr));
    pFile = fopen("data.txt", "rb");
    if (pFile == NULL)
    {
        perror("ファイルが開けません: data.txt");
        return 1;
    }
    fseek(pFile, 0, SEEK_END);
    sizeFile = ftell(pFile);
    fseek(pFile, 0, SEEK_SET);
    countRead = fread(instr, min(sizeFile, DEFAULT_BUFF_LEN), 1, pFile);
    fclose(pFile);
    if (countRead == 0)
    {
        perror("ファイル読み込み失敗: data.txt");
        return 1;
    }
    
    instr_size = min(sizeFile, DEFAULT_BUFF_LEN) * countRead;
    
    /*
     * utf8:instr -> utf16:outstr 変換。
     */
    memset(outstr, 0, sizeof(outstr));
    iResult = Utf8ToUtf16(outstr, sizeof(outstr), instr, instr_size);
    if (iResult == FALSE)
    {
        perror("Utf8ToUtf16() Failed.\n");
        return 1;
    }
    printf("%d 文字変換しました。\n", iResult);
    
    /*
     * ファイルに文字列を書き込み。
     */
    pFile = fopen("out.txt", "wb");
    if (pFile == NULL)
    {
        perror("ファイルが開けません: out.txt");
        return 1;
    }
    bom = 0xfeff;
    memcpy(outbuffbom, &bom, sizeof(wchar_t));
    fwrite(outbuffbom, sizeof(wchar_t), 1, pFile);
    fwrite(outstr, iResult * 2, 1, pFile);
    fclose(pFile);
}

/**
 * 文字コードをUTF-8よりUTF16へと変換。
 * 
 * @param[out] dest 出力文字列UTF-16
 * @param[in]  dest_size destのサイズをワード単位で指定
 * @param[in]  src 入力文字列UTF-8
 * @param[in]  src_size 入力文字列のバイト数
 * 
 * @return 成功時には出力文字列の文字数を戻します。
 *         dest_size に0を指定し、こちらの関数を呼び出すと、変換された
 *         文字列を格納するのに必要なdestのサイズの文字数を戻します。
 *         関数が失敗した場合には、FALSEを戻します。
 */
int Utf8ToUtf16(wchar_t *dest, size_t dest_size, char *src, size_t src_size)
{
                                /**/
    UINT    uCodePage;          /* コードページ */
    DWORD   dwFlags;            /* 処理性能とマッピングのフラグ */
    LPCSTR  lpMultiByteStr;     /* 新しい文字列のバッファのアドレス */
    int     cchMultiByte;       /* バッファのサイズ */
    LPWSTR  lpWideCharStr;      /* ワイド文字の文字列のアドレス */
    int     cchWideChar;        /* 文字列の文字数 */
    int     iResult = 0;
    
    uCodePage       = CP_UTF8;
    dwFlags         = 0;
    lpMultiByteStr  = src;
    cchMultiByte    = src_size;
    lpWideCharStr   = dest;
    cchWideChar     = dest_size;
    iResult = MultiByteToWideChar(uCodePage, dwFlags, lpMultiByteStr
            , cchMultiByte, lpWideCharStr, cchWideChar);
    return iResult;
}