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