c - 如何在mingw中检测命令行参数的字符编码

标签 c windows unicode mingw

假设它们是 ISO-8859-15(Window-1252?)是否安全,或者我可以调用一些函数来查询它吗?最终目标是转换为 UTF-8。


背景:

this question描述的问题出现是因为 XMLStarlet 假定其命令行参数是 UTF-8。在 Windows 下,它们似乎实际上是 ISO-8859-15(Window-1252?),或者至少将以下内容添加到 main 的开头可以使事情正常进行:

char **utf8argv = malloc(sizeof(char*) * (argc+1));
utf8argv[argc] = NULL;

{
    iconv_t windows2utf8 = iconv_open("UTF-8", "ISO-8859-15");
    int i;
    for (i = 0; i < argc; i++) {
        const char *arg = argv[i];
        size_t len = strlen(arg);
        size_t outlen = len*2 + 1;
        char *utfarg = malloc(outlen);

        char *out = utfarg;
        size_t ret = iconv(windows2utf8,
            &arg, &len,
            &out, &outlen);

        if (ret < 0) {
            perror("iconv");
            utf8argv[i] = NULL;
            continue;
        }

        out[0] = '\0';
        utf8argv[i] = utfarg;
    }

    argv = utf8argv;
}

测试编码

以下程序以十进制打印出其第一个参数的字节:

#include <strings.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    for (int i = 0; i < strlen(argv[1]); i++) {
        printf("%d ", (unsigned char) argv[1][i]);
    }
    printf("\n");
    return 0;
}

chcp 报告代码页 850 , 所以字符 æ 和 Æ 应该分别是 145 和 146。

C:\Users\npostavs\tmp>chcp
Active code page: 850

但我们看到报告的 230 和 198 与 1252 匹配:

C:\Users\npostavs\tmp>cmd-chars æÆ
230 198

在代码页之外传递字符会导致有损转换

使用参数αβγ(这些在代码页 1252 中不存在)创建 cmd-chars.exe 的快捷方式给出

C:\Users\npostavs\tmp>shortcut-cmd-chars.lnk
97 223 63

aß 是什么?

最佳答案

您可以调用CommandLineToArgvW调用 GetCommandLineW作为获取 argv 样式的宽字符串数组中的命令行参数的第一个参数。这是唯一可移植的 Windows 方式,尤其是在代码页困惑的情况下;例如,日语字符可以通过 Windows 快捷方式传递。之后,您可以使用 WideCharToMultiByte使用 CP_UTF8 的代码页参数将每个宽字符 argv 元素转换为 UTF-8。

请注意,使用输出缓冲区大小(字节计数)为 0 调用 WideCharToMultiByte 将允许您确定指定字符数(或整个宽字符串)所需的 UTF-8 字节数如果您希望将 -1 作为宽字符数传递以简化代码,则包括空终止符)。然后您可以使用 malloc 等分配所需的字节数。并使用正确的字节数而不是 0 再次调用 WideCharToMultiByte。如果这对性能至关重要,则可能最好采用不同的解决方案,但由于这是获取命令行的一次性函数争论,我想说性能的任何下降都可以忽略不计。

当然,不要忘记释放所有内存,包括使用 CommandLineToArgvW 返回的指针作为参数调用 LocalFree

有关函数及其使用方法的更多信息,请单击链接以查看 MSDN 文档。

关于c - 如何在mingw中检测命令行参数的字符编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25070252/

相关文章:

windows - 在离线 Windows 机器上安装 Python 包(numpy、scipy、statsmodels 等)

c# - 使用正则表达式匹配 C# Unicode 标识符

python-2.7 - 获取适当长度的表情符号

python - Unicode re.sub() 不适用于\g<0>(第 0 组)

c - 格式化 char*,类似于 "printf",但不打印出来

windows - 静默安装 Windows 7 时 startnet.cmd 问题

c++ - VC++/C++ 高性能多线程GUI交易注意事项

计算数组的平均值

java - Pollard rho 整数分解

c - 执行“if…else”语句时出现问题