c - 环境变量和本地化

标签 c windows winapi localization environment-variables

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]);
}

当以英语系统区域设置运行时,它显示的字节与输入的字节相同,即:

06 C7 86 C1 99 93 CF

但是,当使用日语系统区域设置运行时,它显示的输出略有不同:

06 C7 81 45 99 93 CF

这是预期的吗?有没有办法让它返回相同的值,而不管区域设置如何?

最佳答案

显然该字符串不支持某些字符。您可以通过将字符串转换为 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;
}

关于c - 环境变量和本地化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50258899/

相关文章:

windows - 我应该在 Firemonkey 中使用 TMainMenu 来同时支持 Windows 和 OS-X 吗?

windows - Windows 应用程序如何使用多个进程?

代码更正以使 RASENUM 连接在 XP 中工作

c - 为什么指针 +1 包含的内存地址与指向的值的地址 +1 不同

c - 标准C : Storing arrays in off-chip RAM

c - 使用 -lpthread 在 C 中实现多线程

windows - CertCreateCertificateChainEngine 在 Windows 7 中引发错误

c - 为什么 putenv(buf) 无法正常工作,因为 memcpy(buf + 92, "\x00\x14\xe4\xf7", 4) 将 a\x00 字节复制到 buf ?

windows - 在批处理脚本中更改暂停命令的输出

c - 为了拦截错误并生成错误日志条目,在 winapi 窗口过程中返回或执行什么操作