简体   繁体   English

将非英文字符输入到 C# 控制台应用程序中的问题

[英]Problems with the input of non-English characters into a C# console app

I'm trying to build a console C# application with Visual Studio 2010 on the English Windows 7 Ultimate 64-bit.我正在尝试在英语 Windows 7 Ultimate 64 位上使用 Visual Studio 2010 构建控制台 C# 应用程序。 When I try to copy a path with non-ASCII characters and then paste it into my console app the non-ASCII characters turn into ???.当我尝试复制带有非 ASCII 字符的路径,然后将其粘贴到我的控制台应用程序中时,非 ASCII 字符会变成 ???。 Is there any way to fix this?有没有什么办法解决这一问题?

Here's what I'm copying: C:\\Test Folder\\документи这是我要复制的内容: C:\\Test Folder\\документи

And this is the code (after a suggested link above):这是代码(在上面建议的链接之后):

Console.OutputEncoding = System.Text.Encoding.UTF8;
string strLineUserInput = Console.ReadLine();

But even if I change the font, the C:\\Test Folder\\документи still becomes C:\\Test Folder\\?????????但即使我改变了字体, C:\\Test Folder\\документи仍然会变成C:\\Test Folder\\????????? in strLineUserInput variable when I test it with a debugger.当我用调试器测试它时,在strLineUserInput变量中。

Also note that unlike the link "duplicate post", I need these characters on the input.另请注意,与链接“重复帖子”不同,我需要在输入中使用这些字符。

So if I do this then:所以如果我这样做,那么:

Console.InputEncoding = System.Text.Encoding.UTF8;
string strLineUserInput = Console.ReadLine();

My strLineUserInput becomes null if I read the text above.如果我阅读上面的文字,我的strLineUserInput将变为null

Follow these steps:按着这些次序:

  1. Change the console window font to Lucida Console for both when debugging / not debugging.在调试/不调试时,将控制台窗口字体更改为Lucida Console
  2. Execute the following code:执行以下代码:

     public static void Main(String[] args) { Console.OutputEncoding = System.Text.Encoding.GetEncoding("Cyrillic"); Console.InputEncoding = System.Text.Encoding.GetEncoding("Cyrillic"); Console.WriteLine(@"C:\\Test Folder\\документи"); // input C:\\Test Folder\\документи string strLineUserInput = Console.ReadLine(); Console.WriteLine(strLineUserInput); }

The output should be:输出应该是:

C:\Test Folder\документи
C:\Test Folder\документи
C:\Test Folder\документи

[UPDATE] [更新]

Maybe you would like to use the ReadKey method in order to have it working (you still have to use the Lucida Console font):也许你想使用ReadKey方法让它工作(你仍然必须使用Lucida Console字体):

static void Main(string[] args)
{
    Console.OutputEncoding = Encoding.UTF8;
    Console.InputEncoding = Encoding.UTF8;

    string s = @"C:\Test Folder\документи";
    Console.WriteLine(s);

    // input C:\Test Folder\документи
    var strInput = ReadLineUTF();

    Console.WriteLine(strInput);
}

static string ReadLineUTF()
{
    ConsoleKeyInfo currentKey;

    var sBuilder = new StringBuilder();
    do
    {
        currentKey = Console.ReadKey();
        // avoid capturing newline
        if (currentKey.Key != ConsoleKey.Enter)
            sBuilder.Append(currentKey.KeyChar);

    }
    // check if Enter was pressed
    while (currentKey.Key != ConsoleKey.Enter);

    // move on the next line
    Console.WriteLine();

    return sBuilder.ToString();
}

the code below helps me.下面的代码对我有帮助。 Please use Encoding.Unicode instead of Encoding.UTF8请使用Encoding.Unicode而不是 Encoding.UTF8

  Console.OutputEncoding = Console.InputEncoding = Encoding.Unicode;
  Console.Write("Введите свое имя: ");
  string name = Console.ReadLine(); 
  Console.WriteLine($"Привет {name}"); 

This seems like a complete overkill for C# but it worked for me:这对于 C# 来说似乎是一个完全的矫枉过正,但它对我有用:

using System.Runtime.InteropServices;

[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 ReadInputLineAsUTF8()
{
    //I can't seem to find a way not to hardcode the size here???
    const int bufferSize = 1024 * 2;
    byte[] buffer = new byte[bufferSize];

    uint charsRead = 0;
    ReadConsoleW(GetWin32InputHandle(), buffer, bufferSize, out charsRead, (IntPtr)0);

    //Make new array of data read
    byte[] buffer2 = new byte[charsRead * 2];
    for (int i = 0; i < charsRead * 2; i++)
    {
        buffer2[i] = buffer[i];
    }

    //Convert string to UTF-8
    return Encoding.UTF8.GetString(Encoding.Convert(Encoding.Unicode, Encoding.UTF8, buffer2)).Trim();
}

Your text looks like it is in Russian.您的文字看起来像是俄语。

File Explorer is in Unicode.文件资源管理器采用 Unicode。

Console application probably isn't in Unicode.控制台应用程序可能不是 Unicode。

When you paste into your Console window your Unicode characters will convert to a non-Unicode system based on your current system locale.当您粘贴到控制台窗口时,您的 Unicode 字符将根据您当前的系统区域设置转换为非 Unicode 系统。 If your system locale doesn't support Russian, your characters will convert to "?'.如果您的系统区域设置不支持俄语,您的字符将转换为“?”。

Try reviewing your Control Panel > Region and Language settings:尝试查看您的控制面板 > 区域和语言设置:

  1. Open Control Panel打开控制面板
  2. Select Region and Language选择地区和语言
  3. Review Current language for non-Unicode查看非 Unicode 的当前语言
  4. If it's not set to Russian, try "Change system locale" and set to Russian.如果未设置为俄语,请尝试“更改系统区域设置”并设置为俄语。

Its very easy if you just want to have input copy pasted into your text box .如果您只想将输入副本粘贴到文本框中,这非常容易。 Have a check Box Control in your application and you can have code to changed your font something like this .在您的应用程序中有一个复选框控件,您可以使用代码来更改您的字体,如下所示。

enter code here
 private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox1.Checked)
        {
            textBox1.Font = new Font("Your font", 10);
        }
        else 
        {
            textBox1.Font = new Font("Times New Roman", 10);
        }
    }

Or if You are pasting non-english always then you can change the font property of the text box.或者,如果您总是粘贴非英语,那么您可以更改文本框的字体属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM