【问题标题】:How to get a null terminated string from a C# string?如何从 C# 字符串中获取以空字符结尾的字符串?
【发布时间】:2010-05-08 09:37:00
【问题描述】:
  • 我正在与需要以空字符结尾的字符串的服务器通信
  • 如何在 C# 中智能做到这一点?

【问题讨论】:

    标签: c# string null-terminated


    【解决方案1】:

    我认为明智的做法是简单地做。

    string str = "An example string" + char.MinValue; // Add null terminator.
    

    然后将其转换为字节发送到服务器。

    byte[] buffer = ASCIIEncoding.ASCII.GetBytes(str);
    

    当然,您使用什么编码取决于服务器期望的编码。

    【讨论】:

    • char.MinValue 是真正的 C# 方式
    • 这是迄今为止我发现的最简单(也是最可靠)的方法。这应该是公认的答案。
    【解决方案2】:

    我假设你正在实现某种二进制协议,如果字符串是空终止的。你用的是BinaryWriter吗?

    默认BinaryWriter 将字符串作为长度前缀写入。你可以改变这种行为:

    class MyBinaryWriter : BinaryWriter
    {
        private Encoding _encoding = Encoding.Default;
    
        public override void Write(string value)
        {
            byte[] buffer = _encoding.GetBytes(value);
            Write(buffer);
            Write((byte)0);
        }
    }
    

    然后你可以像这样写任何字符串:

    using (MyBinaryWriter writer = new MyBinaryWriter(myStream))
    {
        writer.Write("Some string");
    }
    

    您可能需要调整_encoding 位,具体取决于您的需要。

    您当然可以根据您可能需要传输的其他数据类型的特定需求来扩展该类,从而使您的实际协议实现保持整洁。您可能还需要自己的(非常相似的)BinaryReader

    【讨论】:

    • 我建议使用 base.Write(this._encoding.GetBytes(new char[]{ '\u0000'})) 来编码空终止符。默认的 UTF-16 为 2 个字节,并期望末尾有两个 0 字节。
    • 用“\0”附加值(如果它还没有以它结尾):if (!value.EndsWith("\0")) value += "\0"; 因此使解决方案独立于编码(你没有担心零的数量)。
    【解决方案3】:

    字符串已经以空值结尾。虽然字符串本身不包含空字符,但在内存中,空字符总是跟在字符串后面。

    但是,.NET 中的字符串是 unicode,因此它们在内存中以 UTF-16/UCS-2 的形式存储,并且服务器可能需要不同的编码,通常是 8 位编码。然后您必须将字符串编码为字节数组并在末尾放置一个零字节:

    byte[] data = Encoding.Default.GetBytes(theString);
    byte[] zdata = new byte[data.Length + 1];
    data.CopyTo(zdata, 0);
    

    (zdata 数组在创建时全部用零填充,因此您不必实际将额外的字节设置为零。)

    【讨论】:

    • 修正了一个小错字。我个人对双缓冲区分配不太满意。你可以解决这个问题。话又说回来,琴弦不太可能很大或音量很大。
    • “Null 终止”通常意味着“在第一个 null 处结束”。如果您还允许 .NET 字符串可能包含一个或多个空字符但不终止,则 .NET 字符串不能被视为空终止
    • "字符串已经以空字符结尾。虽然字符串本身不包含空字符,但空字符总是跟在内存中的字符串后面。"我以前从未听说过,也没有在 MSDN 文档上看到任何有关此的信息。能发个出处吗?
    • @John:我第一句话的具体意思是字符串后面已经有一个终止零。如果字符串本身包含一个空字符,它自然不能作为空终止字符串正常工作,但这是这里提出的每个答案都有的问题。
    • @Guffa:Jon 的页面似乎与actual documentation 直接冲突。我不认为 C# 字符串真的是空终止的,编组过程只知道如何对它们进行空终止(而且我不确定它将如何保留嵌入的空值,或者是否有可能)。
    【解决方案4】:

    在字符串末尾添加一个空字符。 .NET 字符串可以包含空字符。

    【讨论】:

    • 我认为他建议使用 'char c = new char()',这将创建 unicode 点 'U+0000'。
    猜你喜欢
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多