在MSDN中似乎没有关于此的任何文档,但显然SetEnvironmentVariableA和GetEnvironmentVariableA似乎与特殊字符的工作方式不同,具体取决于本地化,我想知道这是否是预期的。
我把这个简单的C控制台程序放在一起:
#include <windows.h>
#include <stdio.h>
int main()
{
PUCHAR binIn = "\x06\xC7\x86\xC1\x99\x93\xCF";
UCHAR binUt[16] = {0};
SetEnvironmentVariable("MYVAR", binIn);
GetEnvironmentVariable("MYVAR", binUt, 16);
printf("%X %X %X %X %X %X %X\n", binUt[0], binUt[0], binUt[1], binUt[2], binUt[3], binUt[4], binUt[5], binUt[6]);
}
当使用System Locale作为英语运行时,它会显示与输入相同的字节,即:
06 C7 86 C1 99 93 CF
但是,当使用System Locale作为日语运行时,它会显示略有不同的输出:
06 C7 81 45 99 93 CF
这是预期的吗?有没有办法让它返回相同的值而不管Locale?
答案 0 :(得分:1)
显然,此字符串中不支持某些字符。您可以通过将字符串转换为UTF16并返回来复制问题:
wchar_t* get_unicode(const char* ansi, UINT codepage)
{
if(!ansi) return 0;
int size = MultiByteToWideChar(codepage, 0, ansi, -1, 0, 0);
wchar_t* unicode = malloc(size * sizeof(wchar_t));
MultiByteToWideChar(codepage, 0, ansi, -1, unicode, size);
return unicode;
}
char* get_char(const wchar_t* unicode, UINT codepage)
{
if(!unicode) return 0;
int size = WideCharToMultiByte(codepage, 0, unicode, -1, 0, 0, 0, 0);
char* ansi = malloc(size);
WideCharToMultiByte(codepage, 0, unicode, -1, ansi, size, 0, 0);
return ansi;
}
int main()
{
//932 for Japanese code page
wchar_t* unicode = get_unicode("\x06\xC7\x86\xC1\x99\x93\xCF", 932);
char* ansi = get_char(unicode, 932);
for(int i = 0, len = strlen(ansi); i < len; i++)
printf("%02X ", ansi[i]&0xFF);
printf("\n");
return 0;
}
这是错误的结果:
06 C7 81 45 99 93 CF
你可能在这里做的不多。也许原始日语字符串未正确转换,或者可能不支持某些字符。
使用Unicode轻松解决问题:
int main()
{
SetEnvironmentVariableW(L"MYVAR", L"日本語 ελληνικά");
wchar_t buf[100];
GetEnvironmentVariableW(L"MYVAR", buf, _countof(buf));
MessageBoxW(0, buf, 0, 0);
return 0;
}
如果你的程序的其余部分不是Unicode或无法转换,你可以用UTF8格式而不是UTF16存储宽字符串,如下例所示:
int main()
{
char* utf8 = get_char(L"日本語", CP_UTF8);
wchar_t* unicode = get_unicode(utf8, CP_UTF8);
SetEnvironmentVariableW(L"MYVAR", unicode);
wchar_t buf[100];
GetEnvironmentVariableW(L"MYVAR", buf, _countof(buf));
MessageBoxW(0, buf, 0, 0);
free(utf8);
free(unicode);
return 0;
}