[C#] 在 Windows 里显示 DOS 字符

  最近正好需要在 Windows 里显示 DOS 字符,特别是 ASCII 码 31 及以下 128 及以上的特殊字符。摸索了一下,找到了一个还算可以的解决方案。

重点提示

  1. 采用 CP 437 转换 ASCII 码 128 及以上的字符;

  2. ASCII 小于 32 的字符可以被解释为“控制字符”或“图像字符”;Windows 的代码转换选择前一种解释(例如,CR-LF 作为换行符);

  3. 可以自己继承 Encoding 类,实现图像字符的转换。

背景

  DOS 下面的特殊字符包括三个部分:CHR(0) - CHR(31), CHR(127), CHR(128-255)。

  System.Text.Encoding 类有几个属性,可以返回常用的编码;但是 ASCII 编码只允许 7 位。

代码

下面为了方便,先帖上代码,以后再补上文字。


using System;
using System.Text;

namespace QuickHelp
{
    public class Graphic437Encoding : Encoding
    {
        private static readonly Encoding CP437 = Encoding.GetEncoding(437);
        private const string GraphicCharacters = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼";

        public static bool IsControlCharacter(char c)
        {
            return (c < 32) || (c == 127);
        }

        public static bool ContainsControlCharacter(string s)
        {
            if (s == null)
                throw new ArgumentNullException("s");

            for (int i = 0; i < s.Length; i++)
            {
                if (IsControlCharacter(s[i]))
                    return true;
            }
            return false;
        }

        public static void SubstituteControlCharacters(char[] chars)
        {
            if (chars == null)
                throw new ArgumentNullException("chars");

            SubstituteControlCharacters(chars, 0, chars.Length);
        }

        public static void SubstituteControlCharacters(char[] chars, int index, int count)
        {
            if (chars == null)
                throw new ArgumentNullException("chars");
            if (index < 0 || index > chars.Length)
                throw new ArgumentOutOfRangeException("index");
            if (count < 0 || count > chars.Length - index)
                throw new ArgumentOutOfRangeException("count");

            for (int i = index; i < index + count; i++)
            {
                if (chars[i] < 32)
                    chars[i] = GraphicCharacters[chars[i]];
                else if (chars[i] == 127)
                    chars[i] = '⌂';
            }
        }

        public static string SubstituteControlCharacters(string s)
        {
            if (s == null)
                return null;

            if (!ContainsControlCharacter(s))
                return s;

            char[] chars = s.ToCharArray();
            SubstituteControlCharacters(chars);
            return new string(chars);
        }

        public override int GetByteCount(char[] chars, int index, int count)
        {
            return CP437.GetByteCount(chars, index, count);
        }

        public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
        {
            return CP437.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
        }

        public override int GetCharCount(byte[] bytes, int index, int count)
        {
            return CP437.GetCharCount(bytes, index, count);
        }

        public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
        {
            int charCount = CP437.GetChars(bytes, byteIndex, byteCount, chars, charIndex);
            SubstituteControlCharacters(chars, charIndex, charCount);
            return charCount;
        }

        public override int GetMaxByteCount(int charCount)
        {
            return CP437.GetMaxByteCount(charCount);
        }

        public override int GetMaxCharCount(int byteCount)
        {
            return CP437.GetMaxCharCount(byteCount);
        }
    }
}

参考资料

Code page 437 (Wikipedia)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值