c00000fd
c00000fd

Reputation: 22265

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. 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 ???. Is there any way to fix this?

Here's what I'm copying: 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\????????? in strLineUserInput variable when I test it with a debugger.

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.

Upvotes: 6

Views: 10137

Answers (5)

Larissa Savchekoo
Larissa Savchekoo

Reputation: 7592

the code below helps me. Please use Encoding.Unicode instead of Encoding.UTF8

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

Upvotes: 4

coder3521
coder3521

Reputation: 2646

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.

Upvotes: -1

Alex Filipovici
Alex Filipovici

Reputation: 32561

Follow these steps:

  1. Change the console window font to Lucida Console for both when debugging / not debugging.
  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):

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();
}

Upvotes: 7

Stephen Quan
Stephen Quan

Reputation: 25956

Your text looks like it is in Russian.

File Explorer is in Unicode.

Console application probably isn't in Unicode.

When you paste into your Console window your Unicode characters will convert to a non-Unicode system based on your current system locale. 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
  4. If it's not set to Russian, try "Change system locale" and set to Russian.

Upvotes: 0

c00000fd
c00000fd

Reputation: 22265

This seems like a complete overkill for C# but it worked for me:

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();
}

Upvotes: 0

Related Questions