从控制台
我想从C#控制台读取unicode字符串,例如着想读unicode的,让他USET一个:从控制台
C:\ SVN \D³ebugger的\ src \виталик\的Program.cs
起初我只是试图Console.ReadLine()
这回我c:\SVN\D3ebugger\src\???????\Program.cs
我已经尽力了Console.InputEncoding设置为UTF-8,像这样Console.InputEncoding = Encoding.UTF8
但回到我c:\SVN\D³ebugger\src\???????\Program.cs
,基本上打乱字符串的西里尔部分。
所以随机磕磕绊绊我试图设置这样的编码,Console.InputEncoding = Encoding.GetEncoding(1251);
其中返回c:\SVN\D?ebugger\src\виталик\Program.cs
,这次会破坏³字符。
在这一点上,似乎通过切换encodings为InputStream我一次只能得到一种语言。
我也试着去本地,做这样的事情:
// Code
public static string ReadLine()
{
const uint nNumberOfCharsToRead = 1024;
StringBuilder buffer = new StringBuilder();
uint charsRead = 0;
bool result = ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buffer, nNumberOfCharsToRead, out charsRead, (IntPtr)0);
// Return the input minus the newline character
if (result && charsRead > 1) return buffer.ToString(0, (int)charsRead - 1);
return string.Empty;
}
// Extern definitions
[DllImport("Kernel32.DLL", ExactSpelling = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
static extern bool ReadConsoleW(IntPtr hConsoleInput, [Out] StringBuilder lpBuffer,
uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead, IntPtr lpReserved);
,这是工作的罚款对于非Unicode字符串,但是当我试图使它阅读我的样本串,应用程序崩溃。我试图告诉Visual Studio打破所有异常(包括本机异常),但应用程序仍会崩溃。
我还发现this微软Connect中的开放性错误似乎是说现在从控制台的InputStream中读取Unicode是不可能的。
即使与我的问题没有严格关系,值得注意的是,如果Console.OutputEncoding设置为UTF8,Console.WriteLine能够打印此字符串就好了。
谢谢!
更新1
我要寻找一个解决方案,.NET 3.5
更新2
与我用全部原生代码更新。
这里是一个完全正常的版本在.net 3.5客户端:
class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
static extern bool ReadConsoleW(IntPtr hConsoleInput, [Out] byte[]
lpBuffer, uint nNumberOfCharsToRead, out uint lpNumberOfCharsRead,
IntPtr lpReserved);
public static IntPtr GetWin32InputHandle()
{
const int STD_INPUT_HANDLE = -10;
IntPtr inHandle = GetStdHandle(STD_INPUT_HANDLE);
return inHandle;
}
public static string ReadLine()
{
const int bufferSize = 1024;
var buffer = new byte[bufferSize];
uint charsRead = 0;
ReadConsoleW(GetWin32InputHandle(), buffer, bufferSize, out charsRead, (IntPtr)0);
// -2 to remove ending \n\r
int nc = ((int)charsRead - 2) * 2;
var b = new byte[nc];
for (var i = 0; i < nc; i++)
b[i] = buffer[i];
var utf8enc = Encoding.UTF8;
var unicodeenc = Encoding.Unicode;
return utf8enc.GetString(Encoding.Convert(unicodeenc, utf8enc, b));
}
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
Console.Write("Input: ");
var st = ReadLine();
Console.WriteLine("Output: {0}", st);
}
}
如果你需要大字符串更改ReadLine()中的bufferSize。请注意缓冲区将**两次**字符的字节数。另外,如果你不介意使用Linq,你可以使用:var b = buffer.Take(nc).ToArray();而不是那个丑陋的For循环。 – Jcl 2012-03-09 00:34:16
它工作得很好,谢谢!虽然,我做了一些非常相似的事情(使用ReadConsoleW),这根本不起作用。我会检查我做错了什么并更新。 – VitalyB 2012-03-09 14:52:18
之后您可能没有转换为UTF8。可能输入正常,但输出不是(只是猜测) – Jcl 2012-03-09 15:54:14
这似乎工作正常时,目标.NET 4客户端配置文件,但不幸的是不是在目标.NET 3.5客户端配置文件时。确保将控制台字体更改为Lucida Console。
正如@jcl指出的那样,即使我已经瞄准了.NET4,这只是因为我已经安装了.NET 4.5。
class Program
{
private static void Main(string[] args)
{
Console.InputEncoding = Encoding.Unicode;
Console.OutputEncoding = Encoding.Unicode;
while (true)
{
string s = Console.ReadLine();
if (!string.IsNullOrEmpty(s))
{
Debug.WriteLine(s);
Console.WriteLine(s);
}
}
}
}
你是否在.NET 4.5上,也许?它在.NET 4.0中不起作用。行'控制台。InputEncoding = Encoding.Unicode;'抛出一个异常:“IOException - 参数不正确。” – VitalyB 2012-03-04 15:48:51
我确实安装了VS 11 beta和.NET 4.5 beta。但是,控制台应用程序使用VS 2010和.NET 4客户端配置文件工作。我正在使用Windows 7 x64 SP1。 – Phil 2012-03-04 15:55:34
我可以确认,当您定位.NET 3.5客户端配置文件时,我会得到与您相同的异常。 – Phil 2012-03-04 16:08:35
是否有可能/可以接受的,而不是使用控制台命名管道? – Goyuix 2012-03-06 02:18:44
如果我没有找到解决方案,那么这可能是我会做... – VitalyB 2012-03-06 09:38:20