Print ASCII line art characters in C# console application

前端 未结 5 1981
清歌不尽
清歌不尽 2020-12-09 18:03

I would like to have a C# console application print the extended ASCII Codes from http://www.asciitable.com/. In particular I am looking at the line art characters: 169, 17

相关标签:
5条回答
  • 2020-12-09 18:06

    A small program that modifies the codepage used by the Console.OutputEncoding property to use the characters you desire:

    class Program
    {
        static void Main(string[] args)
        {
            Console.OutputEncoding = System.Text.Encoding.GetEncoding(1252);
            Console.WriteLine((char) 169);
            Console.WriteLine((char) 170);
    
            for(char c = (char)179; c <= (char)218; ++c)
            {
                Console.WriteLine(c);
            }
        }
    }
    

    EDIT:

    So I went ahead and looked up the Unicode equivalents of the box art. There's a few extra glyphs that may be useful to you. That Wikipedia page lists all of their code points.

    I've put together this to try them out:

    class Program
    {
        static void Main(string[] args)
        {
            for(int i = 0x2500; i <= 0x2570; i += 0x10)
            {
                for(int c = 0; c <= 0xF; ++c)
                {
                    Console.Write((char) (i + c));
                }
    
                Console.WriteLine();
            }
        }
    }
    

    For me, quite a few glyphs simply come up as ?, but the standard box-art glyphs we're used to seeing in the old ASCII games do appear for me. Hopefully these will work for you.

    0 讨论(0)
  • 2020-12-09 18:07

    I don't know how to get ASCII to work but you can use Unicode, to some degree, if you want to. It does require that the console be set to a true type font.

    Michael Kaplan's article 'Anyone who says the console can't do Unicode isn't as smart as they think they are' includes the code for this.

    I couldn't get his code to work directly but this worked for me as long as I ran it from a True Type Font Console. The article includes how to set it.

    using System;
    using System.Runtime.InteropServices;
    namespace TestUnicode
    
    {
        class Program
    {
    
    
    
    public static void Main(string[] args) {
        string st = "\u0169\u0129\n\n";
        IntPtr stdout = GetStdHandle(STD_OUTPUT_HANDLE);
        uint written;
        WriteConsoleW(stdout, st, st.Length, out written, IntPtr.Zero);
    }
    
    
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    internal static extern bool WriteConsoleW(IntPtr hConsoleOutput,
                                              string lpBuffer,
                                              int nNumberOfCharsToWrite,
                                              out uint lpNumberOfCharsWritten,
                                              IntPtr lpReserved);
    
    
    internal static bool IsConsoleFontTrueType(IntPtr std) {
     CONSOLE_FONT_INFO_EX cfie = new CONSOLE_FONT_INFO_EX();
        cfie.cbSize = (uint)Marshal.SizeOf(cfie);
        if(GetCurrentConsoleFont(std, false, ref cfie)) {
            return(((cfie.FontFamily & TMPF_TRUETYPE) == TMPF_TRUETYPE));
        }
        return false;
    }
    
    
    
    [DllImport("Kernel32.DLL", ExactSpelling = true)]
    internal static extern IntPtr GetStdHandle(int nStdHandle);
    
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern bool GetCurrentConsoleFont(IntPtr hConsoleOutput,
                                                        bool bMaximumWindow, 
                                                        ref CONSOLE_FONT_INFO_EX lpConsoleCurrentFontEx);
    
    
    
    internal struct COORD {
        internal short X;
        internal short Y;
        internal COORD(short x, short y) {
            X = x;
            Y = y;
        }
    }
    
    [StructLayout(LayoutKind.Sequential)]
    internal unsafe struct CONSOLE_FONT_INFO_EX {
        internal uint cbSize;
        internal uint nFont;
        internal COORD dwFontSize;
        internal int FontFamily;
        internal int FontWeight;
        fixed char FaceName[LF_FACESIZE];
    }
    
    internal const int TMPF_TRUETYPE = 0x4;
    internal const int LF_FACESIZE = 32;
    internal const string BOM = "\uFEFF";
    internal const int STD_OUTPUT_HANDLE = -11; // Handle to the standard output device.
    internal const int ERROR_INVALID_HANDLE = 6;
    internal const int ERROR_SUCCESS = 0;
    internal const uint FILE_TYPE_UNKNOWN = 0x0000;
    internal const uint FILE_TYPE_DISK = 0x0001;
    internal const uint FILE_TYPE_CHAR = 0x0002;
    internal const uint FILE_TYPE_PIPE = 0x0003;
    internal const uint FILE_TYPE_REMOTE = 0x8000;
    internal static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    }
        }
    
    0 讨论(0)
  • 2020-12-09 18:15

    I battled this for days a while back. I don't think it can be done, regardless of what other people say. Now, I was trying to make a Dwarf Fortress style game. If you are doing the same, do what he did. Use images.

    • Faster, because it can make use of graphic acceleration.
    • Easier, because they are tiles and there are LOTS of tutorials on doing that.
    • Well Supported, with things like XNA for the very framework you are already using.
    • Extensible, so you can swap in other images at a later date, for new images like the bearded smiles in DF.
    0 讨论(0)
  • 2020-12-09 18:19

    You can simply use Signs from the ASCII-table in windows.

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("╔═╗");
            Console.WriteLine("╚═╝");
        }
    }
    
    0 讨论(0)
  • 2020-12-09 18:24

    To view correct ascii's on console I just do this:

    Console.OutputEncoding = System.Text.Encoding.GetEncoding(28591);

    To understand ASCII Chart I wrote below code:

    using System;
    
    namespace AsciiChart
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.OutputEncoding = System.Text.Encoding.GetEncoding(28591);
                for (int i = 0; i < 256; i++) {
                   Console.Write(i+"=> ["+(char)i +"]  \n");
                }
                Console.ReadKey();
            }
        }
    }
    

    Let's begin to draw, sample 1:

    using System;
    
    namespace AsciiBorder
    {
        class Program
        {
            static void Main(string[] args)
            {
                int topleft = 218;
                int hline = 196;
                int topright = 191;
                int vline = 179;
                int bottomleft = 192;
                int bottomright = 217;
    
                Console.OutputEncoding = System.Text.Encoding.GetEncoding(28591);
                //draw top left corner
                Write(topleft);
                //draw top horizontal line
                for (int i = 0; i < 10; i++)
                    Write(hline);
                //draw top right corner
                Write(topright);
                Console.WriteLine();
                //draw left and right vertical lines
                for (int i = 0; i < 6; i++)
                {
                    Write(vline);
                    for (int k = 0; k < 10; k++) {
                        Console.Write(" ");
                    }
                    WriteLine(vline);
                }
                //draw bottom left coner
                Write(bottomleft);
                //draw bottom horizontal line
                for (int i = 0; i < 10; i++)
                    Write(hline);
                //draw bottom right coner
                Write(bottomright);
                Console.ReadKey();
            }
            static void Write(int charcode)
            {
                Console.Write((char)charcode);
            }
            static void WriteLine(int charcode)
            {
                Console.WriteLine((char)charcode);
            }
        }
    }
    

    Console Output:

    More info about Latin 1 & ASCII Code Pages

    Completed 3x3 Tic-Tac-Toe like board drawing code: Sample 2

    Code:

    using System;
    
    namespace AsciiBorder
    {
        class Program
        {
            const int topleft = 218, hline = 196, topright = 191, vline = 179, bottomleft = 192, bottomright = 217, cross = 197, topT = 194, bottomT = 193, leftT = 195, rightT = 180;
            const int space = 10/*this determine size of the single cell*/, spacer_ex = (space / 2) + 1;
            static void Main(string[] args)
            {            
                Console.OutputEncoding = System.Text.Encoding.GetEncoding(28591);
                Console.Title = "3x3 Board";
                DrawTop();
                DrawMidSpacer();
                DrawMiddle();
                DrawMidSpacer();
                DrawMiddle();
                DrawMidSpacer();
                DrawBottom();
    
                Console.ReadKey();
            }
            static void DrawBottom() {
                #region bottom
                Write(bottomleft);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(bottomT);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(bottomT);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(bottomright);
    
                Console.WriteLine();
                #endregion
            }
            static void DrawMiddle() {
                #region middle
                Write(leftT);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(cross);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(cross);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(rightT);
    
                Console.WriteLine();
                #endregion
            }
            static void DrawMidSpacer() {
                #region middlespacer
                for (int x = 0; x < spacer_ex; x++)
                {
                    Write(vline);
                    for (int i = 0; i < space; i++)
                        Console.Write(" ");
                    Write(vline);
                    for (int i = 0; i < space; i++)
                        Console.Write(" ");
                    Write(vline);
                    for (int i = 0; i < space; i++)
                        Console.Write(" ");
                    Write(vline);
    
                    Console.WriteLine();
                }
                #endregion
            }
            static void DrawTop() {
                #region top
                Write(topleft);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(topT);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(topT);
                for (int i = 0; i < space; i++)
                    Write(hline);
                Write(topright);
    
                Console.WriteLine();
                #endregion
            }
            static void Write(int charcode)
            {
                Console.Write((char)charcode);
            }
            static void WriteLine(int charcode)
            {
                Console.WriteLine((char)charcode);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题