为什么0x00字符使System.Diagnostics.Debug.WriteLine不写新行?

时间:2011-07-29 12:44:10

标签: c# .net vb.net unicode

Dim hex = "41"
    Dim text As New System.Text.StringBuilder
    For i As Integer = 0 To hex.Length - 2 Step 2
        text.Append(Chr(Convert.ToByte(hex.Substring(i, 2), 16)))
    Next
    System.Diagnostics.Debug.WriteLine(text.ToString)

完美地工作.. System.Diagnostics.Debug.WriteLine将输出本身写入一个新行。

 Dim hex = "4100"
    Dim text As New System.Text.StringBuilder
    For i As Integer = 0 To hex.Length - 2 Step 2
        text.Append(Chr(Convert.ToByte(hex.Substring(i, 2), 16)))
    Next
    System.Diagnostics.Debug.WriteLine(text.ToString)

但是这个失败..(输出本身不是一个新行)是什么解释?

据我所知,System.Diagnostics.Debug.Writeline没有做到这样的事情:

System.Diagnostics.Debug.Write(input)
System.Diagnostics.Debug.Write("\n")

所以无论我输入什么,即使我的输入中有一个终止的00字符,它也应该总是有一个换行符?

3 个答案:

答案 0 :(得分:3)

我怀疑它本身不是Debug.WriteLine - 它是接收输出的Windows控件,它将U + 0000视为“字符串结尾”。

尝试将TextWriterTraceListener写入文件添加到Debug侦听器集合,然后在二进制文件查看器中查看该文件,我怀疑您会看到您认为自己正在编写的每个字符。

答案 1 :(得分:2)

以下是详细描述这里发生的事情:

.net中的string类是一个char数组,从指向数组中第一个char的指针开始,以特殊的“终端”字符\0结束。
当您将00转换为字节时,您会获得0。但是0等于终端字符\0

byte b = (byte)`\0`;\\the value of b will be 0

因此Console.Write将忽略第一个\0之后的所有字符!不仅控制台将采用这种方式,还包括控制组件。例如textBox.Text如果您将字符串应用于具有\0字符的字符串,则\0“包括\0本身后”不会显示任何字符。

修改:

  

据我所知,System.Diagnostics.Debug.Writeline没有做到这样的事情:

System.Diagnostics.Debug.Write(input)
System.Diagnostics.Debug.Write("\n")

我猜测Debug.WriteLine没有以这种方式实现,否则我们就不会注意到这种行为。也许它会将字符串与input + "\n"等新行连接起来。

我可以使用Console.WriteLine程序诊断Resharper。代码是:

[SecuritySafeCritical]
public virtual void WriteLine(string value)
{
    if (value == null)
    {
        this.WriteLine();
    }
    else
    {
        int length = value.Length;
        int num2 = this.CoreNewLine.Length;
        char[] destination = new char[length + num2];
        value.CopyTo(0, destination, 0, length);
        switch (num2)
        {
            case 2:
                destination[length] = this.CoreNewLine[0];
                destination[length + 1] = this.CoreNewLine[1];
                break;

            case 1:
                destination[length] = this.CoreNewLine[0];
                break;

            default:
                Buffer.InternalBlockCopy(this.CoreNewLine, 0, destination, length * 2, num2 * 2);
                break;
        }
        this.Write(destination, 0, length + num2);
    }
}

因此它将字符串值与新行连接起来。所以它会产生同样的效果。

答案 2 :(得分:0)

要解决此问题,并仍然显示 NULL 字符,请在打印字符串之前对字符串执行.Replace("\0", @"\0")