摘自Qt源码: typedef unsigned char Uint8; typedef signed char Int8; typedef unsigned short Uint16; typedef signed short Int16; typedef signed int Int; typedef unsigned int Uint; typedef unsigned short WChar; size_t utf16ToUtf8( char* dest, const WChar* src, size_t bufSize) { Uint8 replacement = '?'; int invalid = 0; Uint8* cursor = (Uint8*)dest; int surrogate_high = -1; const WChar *ch = src; while (*ch) { Uint u = *ch; if (surrogate_high >= 0) { if (u >= 0xdc00 && u < 0xe000) { u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000; surrogate_high = -1; } else { // high surrogate without low *cursor = replacement; ++ch; ++invalid; surrogate_high = -1; continue; } } else if (u >= 0xdc00 && u < 0xe000) { // low surrogate without high *cursor = replacement; ++ch; ++invalid; continue; } else if (u >= 0xd800 && u < 0xdc00) { surrogate_high = u; ++ch; continue; } if (u < 0x80) { *cursor++ = (Uint8)u; } else { if (u < 0x0800) { *cursor++ = 0xc0 | ((Uint8) (u >> 6)); } else { if (u > 0xffff) { // see QString::fromUtf8() and QString::utf8() for explanations if (u > 0x10fe00 && u < 0x10ff00) { *cursor++ = (u - 0x10fe00); ++ch; continue; } else { *cursor++ = 0xf0 | ((Uint8) (u >> 18)); *cursor++ = 0x80 | (((Uint8) (u >> 12)) & 0x3f); } } else { *cursor++ = 0xe0 | (((Uint8) (u >> 12)) & 0x3f); } *cursor++ = 0x80 | (((Uint8) (u >> 6)) & 0x3f); } *cursor++ = 0x80 | ((Uint8) (u&0x3f)); } ++ch; } *cursor = 0; }