Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在mingw中检测命令行参数的字符编码_C_Windows_Unicode_Mingw - Fatal编程技术网

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

C 如何在mingw中检测命令行参数的字符编码,c,windows,unicode,mingw,C,Windows,Unicode,Mingw,可以安全地假设它们是ISO-8859-15(Window-1252?),或者我可以调用一些函数来查询它吗?最终目标是转换为UTF-8 背景: 出现的问题是因为XMLStarlet假定其命令行参数为UTF-8。在Windows下,它们似乎实际上是ISO-8859-15(Windows-1252?),或者至少在main的开头添加了以下内容以使事情正常进行: char **utf8argv = malloc(sizeof(char*) * (argc+1)); utf8argv[argc] = NU

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


背景: 出现的问题是因为XMLStarlet假定其命令行参数为UTF-8。在Windows下,它们似乎实际上是ISO-8859-15(Windows-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;
}
但我们看到230和198报告了哪些匹配:

在代码页之外传递字符会导致有损转换 使用参数
αβγ
(这些参数在代码页1252中不存在)创建到
cmd chars.exe
的快捷方式


哪个是
aß?

你好像在windows下

在这种情况下,可以调用
system()
来运行
CHCP
命令

   #include <stdlib.h>     // Uses: system()
   #include <stdio.h> 
   // ..... 

   // 1st: Store the present windows codepage in a text file:
   system("CMD /C \"CHCP > myenc.txt\"");

   // 2nd: Read the first line in the file:
   FILE *F = fopen("myenc.txt", "r");      
   char buffer[100];
   fgets(buffer, F);
   fclose(F);

   // 3rd: Analyze the loaded string to find the Windows codepage:
   int codepage = my_CHCP_analizer_func(buffer);   

   // The function my_CHCP_analizer_func() must be written for you,
   // and it has to take in account the way in that CHCP prints the information.  
#包括//用途:系统()
#包括
// ..... 
//第一:将当前windows代码页存储在文本文件中:
系统(“CMD/C\”CHCP>myenc.txt\”);
//第二:读取文件中的第一行:
文件*F=fopen(“myenc.txt”、“r”);
字符缓冲区[100];
fgets(缓冲区,F);
fclose(F);
//第3步:分析加载的字符串以查找Windows代码页:
int codepage=my\u CHCP\u analizer\u func(缓冲区);
//必须为您编写函数my_CHCP_analizer_func(),
//它必须考虑CHCP打印信息的方式。
最后,可以检查CHCP发送的代码页,例如:

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

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

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


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

命令行参数位于系统默认代码页中,该代码页随系统设置而变化。您可以指定
“char”
”,而不是指定特定的源字符集,并让
iconv\u open()
了解系统字符集的实际内容:

iconv_t windows2utf8 = iconv_open("UTF-8", "char");

否则,您最好将命令行检索为UTF-16而不是Ansi,然后您可以使用
iconv\u open(“UTF-8”、“UTF-16LE”)
WideCharToMultiByte(CP\u UTF8)
像Chrono建议的那样直接将其转换为UTF-8。

我认为这不起作用,
CHCP
告诉我在代码页850,但当我查看程序接收到的实际值时,它们与1252匹配。代码页850和1252是相似的。请在我提供的链接中更详细地研究Windows代码页。值850是正确的。它是命令行中使用的代码页。如果需要,您可以将其更改为1252。不,它们是不同的。请看我在测试编码标题下添加到问题中的示例程序。好的,我应该投反对票。我会面对现实,无论如何,我不会删除我的答案。哦,我错过了那个选项。虽然它确实让我想知道libiconv是如何计算编码的。libiconv是开源的,所以你可以自己看看它到底做了什么。我没有亲自查看,但我怀疑它使用了或类似的代码,然后将报告的代码页映射到其相应的字符集。看起来它至少明确支持一些代码页,例如:关于通过快捷方式的参数,这一点很好,似乎代码页之外的字符会被系统尽最大努力进行音译,所以这个解决方案是唯一保证获得正确字符的解决方案。
C:\Users\npostavs\tmp>cmd-chars æÆ
230 198
C:\Users\npostavs\tmp>shortcut-cmd-chars.lnk
97 223 63
   #include <stdlib.h>     // Uses: system()
   #include <stdio.h> 
   // ..... 

   // 1st: Store the present windows codepage in a text file:
   system("CMD /C \"CHCP > myenc.txt\"");

   // 2nd: Read the first line in the file:
   FILE *F = fopen("myenc.txt", "r");      
   char buffer[100];
   fgets(buffer, F);
   fclose(F);

   // 3rd: Analyze the loaded string to find the Windows codepage:
   int codepage = my_CHCP_analizer_func(buffer);   

   // The function my_CHCP_analizer_func() must be written for you,
   // and it has to take in account the way in that CHCP prints the information.  
iconv_t windows2utf8 = iconv_open("UTF-8", "char");