Font is right. Why can't I get this unicode character to display in this C# console app?

1.5k Views Asked by At

I have added a font to cmd. (DejaVu Sans Mono) This techrepublic link has the registry hack to add a font to cmd, one can do it for some fonts such as that one.

The font has a unicode non ascii glyph and I can paste that unicode non ascii glyph into the cmd prompt

But my C# program that reads from stdin, is not outputting it

enter image description here

enter image description here

enter image description here

Here is my C# program and its output

My program reads a line from stdin, and writes it.

The problem is that when it writes it, it writes a question mark

The program even has this line

Console.OutputEncoding = System.Text.Encoding.Unicode;

but even with that line it isn't making it output the character

C:\blah>echo ⬕
⬕

C:\blah>type b1.cs
using System;
class Program
{
    static void Main(string[] args)
    {
        Console.OutputEncoding = System.Text.Encoding.Unicode;
        string s;
        s = Console.ReadLine();
        Console.WriteLine(s);

    }
}
C:\blah>b1
⬕
?

C:\blah>

I know I am in good company, because more has the same problem.. but echo can do it, so I should be able to make my program do it

C:\blah>echo ⬕
⬕

C:\blah>more
⬕
?

^C
C:\blah>

added screenshot re cyril's comment

enter image description here

added screenshot re .. comment

A C# program with one line Console.WriteLine("⬕") writes ? It is saved as unicode to preserve that character, and it compiles. But given that it prints a ?, it seems the corruption occurs on output. I can't quite comment on whether corruption also occurs on stdin too. But it looks like it occurs on output.

2

There are 2 best solutions below

3
On BEST ANSWER

You need to set input encoding as well.

Console.InputEncoding = System.Text.Encoding.Unicode;

Updated!

using System;
class Program
{
    static void Main(string[] args)
    {
        Console.OutputEncoding = System.Text.Encoding.Unicode;
        Console.InputEncoding = System.Text.Encoding.Unicode;
        string s;
        s = Console.ReadLine();
        Console.WriteLine(s);

    }
}
0
On

As Htin says, you must change the input encoding.. I want to make some further points about that

When you do chcp num, then it changes both input and output encodings. When you do chcp it only shows you the input encoding

C:\>chcpa
Input encoding is: 862- Hebrew (DOS)
Output encoding is: 862- Hebrew (DOS)
To change encoding, use chcpa 850 or chcpa i 850 or chcpa o 850 or chcpa io 850
For fuller and further options, use chcpa  /?

C:\>chcpa o 850
Input encoding is now: 862- Hebrew (DOS)
Output encoding is now: 850- Western European (DOS)

C:\>chcp
Active code page: 862

C:\>chcpa i 65001
Input encoding is now: 65001- Unicode (UTF-8)
Output encoding is now: 850- Western European (DOS)

C:\>chcp
Active code page: 65001

C:\>

This little program chcpa.csc / chcpa.exe will let you change either input or output encodings, or both

EXE downloadable here

http://ge.tt/api/1/files/4PHsTRN2/0/blob?download

or you could compile it from source code

// this program allows setting of input and output codepages..
// and this program can show how chcp<ENTER> checks only the input codepage
// and chcp 850 or chcp num, changes both the input and output codepages

class chcpautility
{
 static string progname=System.AppDomain.CurrentDomain.FriendlyName;


static void Main(string[] args)
{

progname=progname.Substring(0,progname.Length -4);

if (args.Length==0)
{
   // these aren't equivalent oddly enough System.Console.InputEncoding.WindowsCodePage+"- "+System.Console.InputEncoding.EncodingName);

   System.Console.WriteLine("Input encoding is: "+System.Console.InputEncoding.CodePage+"- "+System.Console.InputEncoding.EncodingName);
   System.Console.WriteLine("Output encoding is: "+System.Console.OutputEncoding.CodePage+"- "+System.Console.OutputEncoding.EncodingName);

   //System.Console.WriteLine("To change encoding, use "+progname+" 850 or "+progname+" i 850 or "+progname+" o 850 or "+progname+" io 850 or chcpa -?"); 
   //prog io 850 is the same as prog 850  

    printbasicusage();
}


if (args.Length==1 && (args[0]=="/?"|args[0]=="-?"|args[0]=="-h"|args[0]=="--help"))
{

  System.Console.WriteLine("progname num e.g. chcpa 850  to change both input and output encodings");
  System.Console.WriteLine("chcpa i 850  would change just the input encoding");
  System.Console.WriteLine("chcpa o 850  would change just the output encoding");
  System.Console.WriteLine("chcpa io 850  would change both input and output encodings. That's the same as chcpa 850");
  System.Console.WriteLine("chcpa<ENTER> will display current encodings");
  System.Console.WriteLine("chcpa showencodings  <-- will list encodings, you can add to the list by editing this source code");

 System.Environment.Exit(1);

}

if (args.Length==1 && (args[0]=="showencodings" | args[0]=="showencoding")) 
{

// from here
// https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx

System.Console.WriteLine("850   ibm850      Western European (DOS)");
System.Console.WriteLine("852   ibm852      Central European (DOS)");
System.Console.WriteLine("862   DOS-862     Hebrew (DOS)  (Can use Courier New for Hebrew)"); 
System.Console.WriteLine("1146  IBM01146    IBM EBCDIC (UK-Euro)");
System.Console.WriteLine("1200  utf-16      Unicode (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
System.Console.WriteLine("1201  unicodeFFFE Unicode (Big endian) (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
System.Console.WriteLine("1252  Windows-1252    Western European (Windows)");
System.Console.WriteLine("1255  windows-1255    Hebrew (Windows)");
System.Console.WriteLine("12000 utf-32      Unicode (UTF-32) (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
System.Console.WriteLine("12001 utf-32BE    Unicode (UTF-32 Big endian) (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
System.Console.WriteLine("20127 us-ascii    US-ASCII");
System.Console.WriteLine("20285 IBM285      IBM EBCDIC (UK)");
System.Console.WriteLine("20424 IBM424      IBM EBCDIC (Hebrew) (Can use Courier New for Hebrew)"); 
System.Console.WriteLine("65000 utf-7       Unicode (UTF-7) (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
System.Console.WriteLine("65001 utf-8       Unicode (UTF-8) (Can use DejaVu Sans Mono, or Droid Sans Mono for Unicode)"); 
 System.Environment.Exit(1);

}




if (args.Length==1)
{
  //System.Text.Encoding ei=System.Console.InputEncoding;  //so can later say what it was
  //System.Text.Encoding eo=System.Console.OutputEncoding; //so can later say what it was

  System.Console.InputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[0]));
  System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[0]));

   //System.Console.WriteLine("Input encoding was: "+ei.CodePage+"- "+ei.EncodingName);
   //System.Console.WriteLine("Output encoding was: "+eo.CodePage+"- "+eo.EncodingName);


   System.Console.WriteLine();

   System.Console.WriteLine("Input encoding is now: "+System.Console.InputEncoding.CodePage+"- "+System.Console.InputEncoding.EncodingName);
   System.Console.WriteLine("Output encoding is now: "+System.Console.OutputEncoding.CodePage+"- "+System.Console.OutputEncoding.EncodingName);

}
if (args.Length==2) 
{
//System.Console.WriteLine("Usage- prog i o num e.g. prog i 850 or prog o 850 or prog io 850");

  //System.Text.Encoding ei=System.Console.InputEncoding;  //so can later say what it was
  //System.Text.Encoding eo=System.Console.OutputEncoding; //so can later say what it was

 if (args[0]=="i") System.Console.InputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[1]));
 if (args[0]=="o") System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[1]));
 if (args[0]=="io") {
  System.Console.InputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[1]));
  System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(int.Parse(args[1]));
 }


   //System.Console.WriteLine("Input encoding was: "+ei.CodePage+"- "+ei.EncodingName);
   //System.Console.WriteLine("Output encoding was: "+eo.CodePage+"- "+eo.EncodingName);


   //System.Console.WriteLine();

   System.Console.WriteLine("Input encoding is now: "+System.Console.InputEncoding.CodePage+"- "+System.Console.InputEncoding.EncodingName);
   System.Console.WriteLine("Output encoding is now: "+System.Console.OutputEncoding.CodePage+"- "+System.Console.OutputEncoding.EncodingName);


//System.Console.OutputEncoding=System.Text.Encoding.GetEncoding(65001);


} //if


if (args.Length>2) {System.Console.WriteLine("Too many parameters, check usage, try chcpa<ENTER>");}

} //main

public static void printbasicusage()
{
   System.Console.WriteLine("To change encoding, use "+progname+" 850 or "+progname+" i 850 or "+progname+" o 850 or "+progname+" io 850"); 
   //prog io 850 is the same as prog 850  
   System.Console.WriteLine("For fuller and further options, use " + progname + "  /?");

} //printbasicusage()

} //class