npo*_*avs 3 c windows unicode mingw
假设它们是 ISO-8859-15(Window-1252?)是否安全,或者我可以调用一些函数来查询它吗?最终目标是转换为 UTF-8。
出现此问题所描述的问题是因为 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;
}
Run Code Online (Sandbox Code Playgroud)
以下程序以十进制打印出其第一个参数的字节:
#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;
}
Run Code Online (Sandbox Code Playgroud)
chcp报告代码页850,因此字符 æ 和 Æ 应分别为 145 和 146。
C:\Users\npostavs\tmp>chcp
Active code page: 850
Run Code Online (Sandbox Code Playgroud)
但是我们看到 230 和 198 报告匹配1252:
C:\Users\npostavs\tmp>cmd-chars æÆ
230 198
Run Code Online (Sandbox Code Playgroud)
制作cmd-chars.exe带参数的快捷方式???(这些在代码页 1252 中不存在)给出
C:\Users\npostavs\tmp>shortcut-cmd-chars.lnk
97 223 63
Run Code Online (Sandbox Code Playgroud)
这是aß?.
小智 5
您可以通过调用GetCommandLineW作为第一个参数来调用CommandLineToArgvW,以获取宽字符串样式数组中的命令行参数。这是唯一可移植的 Windows 方式,尤其是代码页混乱时;例如,可以通过 Windows 快捷方式传递日语字符。之后,您可以使用带有代码页参数的WideCharToMultiByte将每个宽字符元素转换为 UTF-8。argvCP_UTF8argv
请注意,WideCharToMultiByte使用输出缓冲区大小(字节数)为 0 进行调用将允许您确定指定字符数所需的 UTF-8 字节数(或者如果您希望传递 -1,则包括空终止符在内的整个宽字符串)作为简化代码的宽字符数)。然后,您可以使用mallocet al分配所需的字节数。并WideCharToMultiByte使用正确的字节数而不是 0 再次调用。如果这对性能至关重要,那么不同的解决方案可能是最好的,但由于这是获取命令行参数的一次性函数,我会说任何减少在性能上可以忽略不计。
当然,不要忘记释放所有内存,包括LocalFree使用返回的指针CommandLineToArgvW作为参数进行调用。
有关这些功能以及如何使用它们的更多信息,请单击链接以查看 MSDN 文档。