gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:20:15 31 4
gpt4 key购买 nike

假设它们是 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/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com