我们如何确定一个字符是否属于特定的代码页?或者我们如何确定一个字符是否适合应用程序的当前活动 IME。
4 回答
- 首先,使用MultiByteToWideChar将您的 UTF-8 字符串转换为 UTF-16
- 现在,使用WideCharToMultiByte将所需的代码页作为第一个参数传递来反转该过程。
如果使用任何无效字符,使用该WC_ERR_INVALID_CHARS
标志和 WideCharToMultiByte 将彻底失败。如果您想知道目标代码页中没有表示哪些字符,请使用 lpDefaultChar 和 lpUsedDefaultChar 参数。
LPCWSTR pszUtf16; // converted from utf8 source character
UINT nTargetCP = CP_ACP;
BOOL fBadCharacter = FALSE;
if(WideCharToMultiByte(nTargetCP,WC_NO_BEST_FIT_CHARS,pszUtf16,NULL,0,NULL,&fBadCharacter)
{
if(fBadCharacter)
{
// at least one character in the string was not represented in nTargetCP
}
}
前两个答案正确建议使用 MultiByteToWideChar 然后 WideCharToMultiByte 将您的 UTF-8 字符转换为 UTF-16,然后转换为当前的 Windows 代码页(CP_ACP)。检查 WideCharToMultiByte 的结果,看转换是否成功。
最初的问题不清楚的是,您在印地语方面遇到了特殊问题。正如 Chris Becke 指出的那样,对于这种语言,您的问题毫无意义,因为印地语没有 Windows ANSI 代码页。因此,您永远无法将印地语字符转换为 CP_ACP,WideCharToMultiByte 将始终失败。
要在 Windows 上使用印地语,据我了解,您必须是调用 Unicode API 的 Unicode 应用程序。
使用 windows 函数 WideCharToMultiByte 和 MultiByteToWideChar 您可以在 UTF-8 和 16 位 Unicode 字符之间进行转换。这些函数有参数来指定代码页并指定遇到无效字符时的行为。
谢谢克里斯..我正在运行以下代码
#define CP_HINDI 0
#define CP_JAPANESE 932
#define CP_ENGLISH 1252
wchar_t wcsStringJapanese = 'あ';
wchar_t wcsStringHindi = 'र';
wchar_t wcsStringEnglish = 'A';
int main()
{
BOOL usedDefaultCharacter = FALSE;
/* Test for ENGLISH */
WideCharToMultiByte( CP_ENGLISH,
0, &wcsStringEnglish,
-1,
NULL,
0,
NULL,
&usedDefaultCharacter);
printf("usedDefaultCharacters for English? %d \n",usedDefaultCharacter);
usedDefaultCharacter = FALSE;
/*TEST FOR JAPANESE */
WideCharToMultiByte( CP_JAPANESE,
0,
&wcsStringJapanese,
-1,
NULL,
0,
NULL,
&usedDefaultCharacter);
printf("usedDefaultCharacters for Japanese? %d \n",usedDefaultCharacter);
//TEST FOR HINDI
usedDefaultCharacter = FALSE;
WideCharToMultiByte( CP_HINDI,
0,
&wcsStringHindi,
-1,
NULL,
0,
NULL,
&usedDefaultCharacter);
printf("usedDefaultCharacters for Hindi? %d \n",usedDefaultCharacter);
}
上面的代码返回:
usedDefaultCharacters 用于英语?0
usedDefaultCharacters 用于日语?0
usedDefaultCharacters 印地语?1
第三行不正确,因为印地语的代码页是 0 ,并且传递的字符串由印地语字符组成,但 usedDefaultChar 仍然设置为 1 .. 这不应该是这种情况。