【问题标题】:Print ASCII line art characters in C# console application在 C# 控制台应用程序中打印 ASCII 线条艺术字符
【发布时间】:2010-12-22 16:09:04
【问题描述】:

我想让 C# 控制台应用程序打印来自 http://www.asciitable.com/ 的扩展 ASCII 代码。特别是我正在查看线条艺术字符:169、170、179-218。不幸的是,当我尝试时,我最终得到了 218 的“Ú”,并希望看到来自 http://www.csharp411.com/ascii-table/ 的其他字符。

我知道 ASCII 仅指定字符代码 0 - 127。我发现另一个帖子引用了 SetConsoleOutputCP(),但无法让它在 C# 类中工作或找到如何做的示例所以。

是否可以在 C# 控制台应用程序中打印线​​条艺术字符?如果有人可以提供示例或代码的 URL 吗?

【问题讨论】:

    标签: c#


    【解决方案1】:

    一个修改 Console.OutputEncoding 属性使用的代码页以使用您想要的字符的小程序:

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

    编辑:

    所以我继续查找Unicode equivalents of the box art。有一些额外的字形可能对您有用。该维基百科页面列出了他们所有的代码点。

    我把这个放在一起来试试:

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

    对我来说,很多字形只是简单地以? 出现,但我们习惯于在旧 ASCII 游戏中看到的标准盒子艺术字形对我来说确实出现了。希望这些对您有用。

    【讨论】:

    • 我试过 437,对我不起作用。代码页 1252 产生了他在示例中使用的所需扩展 ASCII 字符。
    • 这似乎提供了一个更改输出编码的示例。不幸的是,我得到了原始输出而不是艺术线条。 @Ron 我也尝试了 437 并得到了相同的结果。
    • 我已经在两个单独的盒子(Windows XP 和 Windows 7)上尝试过这个,并且能够使用代码页 1252 获得线条艺术。这两个盒子都使用美国版本的 Windows,所以不是确定不同版本的 Windows 的效果是什么,或者 Mono 在非 Windows 机器上的结果是什么。
    • @Joshua 感谢您的反馈,我使用美国版的 Windows XP Professional Version 2002 Service Pack 3 进行本地开发,使用 Windows Server 2008 进行“部署”。我将在其中一台远程服务器上测试代码。
    • @Joshua 它在我的远程服务器 2008 中工作,所以我将把它标记为已回答。我将继续查看我可以确定的不合作的本地 XP 环境。
    【解决方案2】:

    要在控制台上查看正确的 ascii,我只需这样做:

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

    为了理解 ASCII 图表,我写了以下代码:

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

    让我们开始画画吧,示例 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);
            }
        }
    }
    

    控制台输出:

    更多关于Latin 1 & ASCII Code Pages的信息

    已完成 3x3 井字游戏样板绘图代码:示例 2

    代码:

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

    【讨论】:

      【解决方案3】:

      您可以在 windows 中简单地使用 ASCII 表中的符号。

      class Program
      {
          static void Main(string[] args)
          {
              Console.WriteLine("╔═╗");
              Console.WriteLine("╚═╝");
          }
      }
      

      【讨论】:

      • 这确实有效(至少对我在美国 Windows 7 的 PowerShell 控制台中)。有趣的是,它只有在使用 Console.Write/Writeline 方法时才能正常工作。如果我执行 Console.OpenStandardOutput() 然后使用生成的流来写入文本,它就会出现乱码。我尝试了几种变体,包括在OpeningStandardOutput 之前将OutputEncoding 更改为1252,以及在写入stdout 流时构建一个具有1252 编码的StreamWriter。没运气。我想知道 Console.WriteLine 有什么不同。
      • 如果使用 StreamWriter,请尝试 CP850
      【解决方案4】:

      前段时间我和这个斗争了好几天。我不认为这是可以做到的,不管别人怎么说。现在,我正在尝试制作一款矮人要塞风格的游戏。如果你也在做同样的事情,就做他所做的。使用图片。

      • 更快,因为它可以利用 图形加速。
      • 更简单,因为它们是瓷砖和 有很多关于做的教程 那个。
      • 得到很好的支持,例如 XNA 对于你的框架 已经在使用了。
      • 可扩展,因此您可以更换其他 稍后的图像,对于新的 像 DF 中的大胡子微笑这样的图像。

      【讨论】:

      • 它不是为了游戏 :( 这是一个商业应用程序,所以我需要能够在控制台窗口中看到结果,我希望能够获得类似的输出到文件以进行日志记录/审计事后。
      • 这很酷。除了你之外,我更多地为可能出现的人回答了这个问题。
      【解决方案5】:

      我不知道如何让 ASCII 工作,但你可以在某种程度上使用 Unicode,如果你愿意的话。它确实要求将控制台设置为真字体。

      Michael Kaplan 的article '任何说控制台不能处理 Unicode 的人都没有他们想象的那么聪明'包括了这个代码。

      我无法让他的代码直接运行,但只要我从 True Type 字体控制台运行它,它就对我有用。文章包括如何设置它。

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

      【讨论】:

      • 我正在使用 VS 2010 并收到错误“不安全代码可能仅在使用 /unsafe 编译时出现。我必须查看那个。
      • 好的,在构建选项卡上更改项目属性以允许不安全代码后,我让项目运行,但仍然不相信我看到了我在寻找的东西。
      • 您需要从设置为 True Type 字体的控制台运行它,因此直接从 VS 运行项目将不起作用。我链接到的文章描述了如何设置字体。
      • 我的控制台字体默认为 Lucida Console。我确实看过这篇文章,但我没有构建和运行。我会尝试...不幸的是,我得到了与以前相同的结果。这可能与我的环境有关。
      猜你喜欢
      • 2011-01-11
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多