3

How to convert a simple string to a null-terminated one?

Example:

Example string: "Test message"
Here are the bytes:

54 65 73 74 20 6D 65 73 73 61 67 65

I need string with bytes like follows:

54 00 65 00 73 00 74 00 20 00 6D 00 65 00 73 00 73 00 61 00 67 00 65 00 00

I could use loops, but will be too ugly code. How can I make this conversion by native methods?

4

4 回答 4

13

看起来您想要一个以 null 结尾的 Unicode 字符串。如果字符串存储在变量str中,这应该有效:

var bytes = System.Text.Encoding.Unicode.GetBytes(str + "\0");

看到它运行。)

请注意,生成的数组末尾将有三个零字节。这是因为 Unicode 使用两个字节表示字符。第一个零是原始字符串中最后一个字符的一半,接下来的两个是 Unicode 如何编码空字符'\0'。(换句话说,使用我的代码的空字符比您最初指定的多一个,但这可能是您真正想要的。)

于 2013-04-10T15:23:22.450 回答
6

C# 字符串的一些背景知识是一个很好的起点。

C# 字符串的内部结构与 C 字符串不同。a) 它是 unicode,就像 'char' b) 它不是以 null 结尾的 c) 它包括许多 C/C++ 中需要的实用程序函数。

它如何在没有空终止的情况下逃脱?简单的!C# String 在内部管理一个 char 数组。C# 数组是结构,而不是指针(如在 C/C++ 中)。因此,他们知道自己的长度。C/C++ 中的 Null 终止是必需的,以便字符串实用程序函数(如 strcmp())能够检测内存中字符串的结尾。

c# 中确实存在空字符。

string content = "This is a message!" + '\0';

这将为您提供一个以空终止符结尾的字符串。重要的是,空字符是不可见的,不会出现在任何输出中。它将显示在调试窗口中。当您将字符串转换为字节数组(用于保存到磁盘和其他 IO 操作)时,它也会出现,但如果您这样做Console.WriteLine(content),它将不可见。

您应该了解为什么要使用空终止符,以及为什么要避免使用循环构造来获得所需的内容。除非您最终转换为字节数组,否则以空结尾的字符串在 c# 中是相当无用的。通常,只有当您想通过网络或 USB 设备将字符串发送到本机方法时,您才会这样做。

了解如何获取字节也很重要。在 C/C++ 中,一个 char 存储为 1 个字节(8 位),编码为 ANSI。在 C# 中,编码是 unicode,它是两个字节(16 位)。Jon Skeet 的回答向您展示了如何获取 unicode 中的字节。

于 2013-04-10T15:46:40.310 回答
1

面面相觑,但可能有用的答案。如果您在屏幕上以十六进制输出后,如您所显示的那样,您需要执行两个步骤:

  1. 将字符串(末尾带有空字符'\0')转换为字节数组
  2. 转换以十六进制编码的字节字符串表示
  3. 与空格交错
  4. 打印到屏幕

尝试这个:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace stringlulz
{
    class Program
    {
        static void Main(string[] args)
        {
            string original = "Test message";

            byte[] bytes = System.Text.Encoding.Unicode.GetBytes(original + '\0');

            var output = bytes.Aggregate(new StringBuilder(), (s, p) => s.Append(p.ToString("x2") + ' '), s => { s.Length--; return s; });


            Console.WriteLine(output.ToString().ToUpper());
            Console.ReadLine();
        }
    }
}

输出是:

54 00 65 00 73 00 74 00 20 00 6D 00 65 00 73 00 73 00 61 00 67 00 65 00 00 00

于 2013-04-10T15:58:24.573 回答
0

这是一个经过测试的 xml 命令空终止的 C# 示例,效果很好。

strCmd       = @"<?xml version=""1.0"" encoding=""utf-8""?><Command name=""SerialNumber"" />";
sendB        = System.Text.Encoding.UTF8.GetBytes(strCmd+"\0");
sportin.Send = sendB;
于 2016-09-26T22:16:31.807 回答