3

iOSに移植する必要があるWin32関数があります:

// Loads UTF-8 file and converts to a UTF-16 string

bool LoadUTF8File(char const *filename, wstring &str)
{
    size_t size;
    bool rc = false;
    void *bytes = LoadFile(filename, &size);
    if(bytes != 0)
    {
        int len = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)bytes, size, 0, 0);
        if(len > 0)
        {
            str.resize(len + 1);
            MultiByteToWideChar(CP_UTF8, 0, (LPCCH)bytes, size, &str[0], len);
            str[len] = '\0';
            rc = true;
        }
        delete[] bytes;
    }
    return rc;
}

// LoadFile returns the loaded file as a block of memory
// There is a 3 byte BOM which MultiByteToWideChar seems to ignore
// The text in the file is encoded as UTF-8

これには、Objective C ではなく C++ を使用しており、mbstowcs と _mbstowcs_l を使用しようとしています。MultiByteToWideChar と同じようには動作しないようです。たとえば、attaché という単語の末尾にあるアクセント付きの文字は正しく変換されません (Win32 バージョンでは正しく変換されます)。標準ライブラリのどこかに「UTF-8 to UTF-16」関数はありますか?

Win32 バージョンには、私が気付いていないバグがありますか?

MultiByteToWideChar から返される長さが、mbstowcs から返される長さよりも短くなっています。

奇妙なことに、この小さなテストケースでは

    char *p = "attaché";

    wstring str;
    size_t size = strlen(p);
    setlocale(LC_ALL, "");
    int len = mbstowcs(null, p, size);
    if(len > 0)
    {
        str.resize(len + 1);
        mbstowcs(&str[0], p, size);
        str[len] = '\0';
    }
    TRACE(L"%s\n", str.c_str());

    len = MultiByteToWideChar(CP_UTF8, 0, p, size, null, 0);
    if(len > 0)
    {
        str.resize(len + 1);
        MultiByteToWideChar(CP_UTF8, 0, p, size, &str[0], len);
        str[len] = '\0';
    }
    TRACE(L"%s\n", str.c_str());

mbcstowcs から正しい出力が得られ、MultiByteToWideChar が誤って最後の文字を 65533 (REPLACEMENT_CHARACTER) に変換します。今、私は混乱しています...

4

1 に答える 1

0

これに C++ を使用することにこだわっていますか? それとも、これまでに選択した方法で、Objective-C でも使用できるようになっていますか?

Objective-C[yourUTF8String dataUsingEncoding:NSUTF16StringEncoding]では、文字列の UTF-16 表現のバイトを含む NSData を取得するために使用できます。


追加の仮説: 例で正しく変換されない「é」文字は、ソリューションが NFD 形式 (または NFC 形式、いずれか) をとらない可能性があるという事実によっても説明される可能性があることに注意してください。これは、「é」文字が NFD で「アキュート アクセント付きの文字 'e'」のようにエンコードされている場合、正しく解釈されない可能性があることを意味しますが、NFC 形式 (「アクセント付き e 文字」、つまりプレ・合成キャラ直接)となります。またはその逆。

これは 1 つの仮説にすぎません。実際には、予想される "é" 文字ではなく、どのような結果が得られるかによって異なりますが、確認する価値はあります。

于 2012-10-09T16:43:27.960 に答える