在.NET中读取UTF8编码的命令行(C#)

时间:2013-02-22 09:16:46

标签: .net command-line utf-8

我希望能够在我正在编写的.NET控制台程序中处理UTF8编码的命令行参数。不幸的是,“args”数组都传递给Main()函数,而Environment类成员(CommandLine和GetCommandLineArgs())已经(错误地)转换为Unicode,似乎将命令行视为单字节扩展-ascii。

例如,UTF8中的U + 2019(关闭单撇号)是0xe2 0x80 0x99。在1252代码段中,0x80是欧元符号(U + 20ac),0x99是“TM”符号(U + 2122)。 (0xe2是带旋律的“a”,即U + 00e2,因此不会改变)当我在命令行中传递这三个字节时,字符串的“char”元素是0x00e2 0x20ac和0x2122

有没有办法告诉.NET将命令行解释为UTF8,或者获取原始的,未处理的命令行(我可以愉快地将其转换为Unicode字符串)?

更新

关注dletozeun的回答

Windows会做奇怪的事情 - 特别是如果它是XP(当我第一次提出这个问题时我正在使用它)。无论您是尝试从批处理文件调用.NET命令行程序还是直接从命令提示符调用.NET命令行程序,事情似乎都会有所不同。这可能是非常好的理由™,但我不知道。无论如何,它应该帮助任何人,这是我发现的:

命令行

打开标准命令提示符窗口并输入以下命令:

UTF8Cmd.exe abc’def

其中UTF8Cmd是包含dletozeun解决方案的测试程序,中间字符是0xe2,0x80,0x99(U + 2019的UTF8字节 - 关闭单撇号)产生以下输出(显示之前的参数)在dletozeun的代码之后,作为一个字符串并以十六进制转储:

    Raw : "abcâ?Tdef"    61 62 63 e2 20ac 2122 64 65 66
    UTF8: "abc'def"      61 62 63 2019 64 65 66

显示原始参数(Raw)已从1252代码页字节值中修改为其Unicode等价物,但发布的代码已将它们转换回正确的值(U + 2019)

批处理文件

不幸的是,将上述内容放入批处理文件中并不起作用......会发生完全不同的错位,产生:

    Raw : "abcÔÇÖdef"    61 62 63 d4 c7 d6 64 65 66
    UTF8: "abc???def"    61 62 63 fffd fffd fffd 64 65 66

原始字节已被破坏成奇怪的东西,这可能是无效的UTF8,因此处理后的fffd

但是,@ mvp建议首先使用chcp 65001(之后重置) 无需 dletozeun的代码:

Active code page: 65001
    Raw : "abc’def"      61 62 63 2019 64 65 66
    UTF8: "abc�def"      61 62 63 fffd 64 65 66
Active code page: 850

曾经试过这个,正如我在下面的评论中所指出的那样,但那是在一个完全失败的XP盒子上(它甚至看起来没有运行命令,并且离开了命令 - 提示处于一种奇怪的状态)。刚刚尝试回答答案 - 在Windows 7的盒子上 - chcp 65001命令就像我希望的那样,当我最初问这个问题的时候!

1 个答案:

答案 0 :(得分:2)

我知道现在已经很晚了,但我也遇到了这个问题,并没有找到任何答案。我设法找到了一个解决方案,所以这就是我在参数列表中处理UTF8编码字符所做的工作:

    // Handle UTF8 encoded characters
    byte[] argBytes =  System.Text.Encoding.Default.GetBytes( System.String.Join( " ", System.Environment.GetCommandLineArgs() ) );
    string argString = System.Text.Encoding.UTF8.GetString( argBytes );
    string[] args = argString.Split( ' ' );