c#十六进制字节0x09(ascii - > tab)到“\ t”字符串

时间:2013-08-02 16:39:18

标签: c# character-encoding

我需要将文本文件的字节数组转换为它的字符串字符表示形式。

例如,如果我的文本文件包含:

你好(tab)那里(换行)朋友

我想将其转换为数组:

my_array  = {'h', 'e' ,'l','l','o', '\t', 't', 'h','e','r','e', '\r','\n', 'f', 'r' ,'i','e','n', 'd'};

我将控制字符转换为其转义字符串时遇到了问题,即:

  
      
  • 0x09 =' \ t&#39 ;;
  •   
  • 0x0D =' \ r';
  •   
  • 0x0A =' \ n';
  •   

我试过这个,但标签和新行没有在这里表示:

byte[] text_bytes = File.ReadAllBytes("ok.txt");
char[] y = Encoding.ASCII.GetChars(text_bytes);

我知道我可以循环遍历每个字节并有条件查找0x09如果找到它,然后替换为"\t",但我想知道是否有某些内容内置。

4 个答案:

答案 0 :(得分:2)

有几种方法可以做到。最简单的方法是将整个文件加载到内存中:

string theText = File.ReadAllText(filename);

然后使用string.Replace替换您感兴趣的项目:

// "escaping" the '\t' with '\\t' makes it write the literal characters '\' and 't'
theText = theText.Replace("\t", "\\t");

theText = theText.Replace("\r", "\\r");
theText = theText.Replace("\n", "\\n");

然后你可以创建你的角色数组。如果您确定它是所有ASCII文本,则可以使用Encoding.ASCII

byte[] theChars = Encoding.ASCII.GetBytes(theText);

或者,如果你想要一个字符数组:

char[] theChars = theText.ToCharArray();

这可能会足够快到达你的目的。您可以通过单次传递字符串,逐个字符地阅读并复制到StringBuilder来加快速度:

StringBuilder sb = new StringBuilder(theText.Length);
foreach (char c in theText)
{
    switch (c)
    {
        case '\t' : sb.Append("\\t"); break;
        case '\r' : sb.Append("\\r"); break;
        case '\n' : sb.Append("\\n"); break;
        default : sb.Append(c); break;
    }
}

byte[] theChars = Encoding.ASCII.GetBytes(sb.ToString());

答案 1 :(得分:1)

如果要转义所有控制字符,则可以使用Regex.Escape。

string myText = File.ReadAllLines("ok.txt");

//to optimize, you could remove characters that you know won't be there (e.g. \a)
Regex rx = new Regex(@"[\a\e\f\n\r\t\v]", RegexOptions.Compiled); 

myText = rx.Replace(myText, m =>  { return Regex.Escape(m.Value); });

Console.WriteLine(myText);

您无法以发布的方式将其转换为char数组,因为转义的控制字符将计为两个字符(\t)。但如果你不介意每个角色分开,你可以简单地做

char[] myCharArray = myText.ToCharArray();

答案 2 :(得分:0)

如果您不介意它比手动解决方案慢一点,那么您可以使用CodeDomProvider(这可能足够快)。

我在这里找到了示例代码:http://code.google.com/p/nbehave-cf/source/browse/trunk/CustomTool/StringExtensions.cs?spec=svn5&r=5

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;

namespace CustomTool
{
    public static class StringExtensions
    {
        public static String ToLiteral(this String input)
        {
            using (var writer = new StringWriter())
            {
                using (var provider = CodeDomProvider.CreateProvider("CSharp"))
                {
                    provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
                    return writer.ToString();
                }
            }
        }
    }
}

您可以使用Encoding.Ascii.ReadString()阅读字符串来使用它,然后使用.ToLiteral()将其转换为字符串,然后.ToCharArray()以获得最终结果。

这给出了正确的结果,例如:

// You would do (using your sample code):
// string test = Encoding.ASCII.GetString(text_bytes);

string test = "hello\tthere\nfriend";

char[] result = test.ToLiteral().ToCharArray();

如果您检查result,您会看到它具有正确的字符。

但是,我只是使用循环和switch语句来转换字符。它易于编写和理解,而且效率更高。

答案 3 :(得分:0)

在“y”数组中,“转义字符”的实际值(0x09,0x0D等)将带有不可打印的字符作为“文本”。

当你写\ t,\ n,\ r \ n等时,你可能写了(char)0x09,(char)0x0D这就是数据写入的内容。换句话说,“\ t”字符不存在!

无论你是自己动手还是使用现有的库,都会有人将0x09映射到“\ t”转义序列并将其注入你的字符串。