如何将字符串转换为以null结尾的字符串?
如何将简单字符串转换为以null结尾的字符串?
例:
示例字符串:“测试消息”
这是字节:
54 65 73 74 20 6D 65 73 73 61 67 65
我需要字符串,如下所示:
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
我可以使用循环,但代码太难了。 如何通过本机方法进行此转换?
看起来你想要一个以null结尾的Unicode字符串。 如果字符串存储在变量str
,则应该可以:
var bytes = System.Text.Encoding.Unicode.GetBytes(str + "\0");
( 见它跑 。)
请注意,结果数组的末尾将包含三个零字节。 这是因为Unicode使用两个字节表示字符。 第一个零是原始字符串中最后一个字符的一半,接下来的两个是Unicode如何编码空字符'\0'
。 (换句话说,使用我的代码有一个额外的空字符比你最初指定的,但这可能是你真正想要的。)
关于c#字符串的一点背景是一个很好的起点。
C#字符串的内部结构与C字符串不同。 a)它是unicode,因为它是’char’b)它不是空终止的c)它包含许多在C / C ++中你需要的实用函数。
如何摆脱没有空终止? 简单! 在内部,C#String管理一个char数组。 C#数组是结构,而不是指针(如在C / C ++中)。 因此,他们知道自己的长度。 需要C / C ++中的Null终止,以便strcmp()之类的字符串实用程序函数能够检测内存中字符串的结尾。
空字符确实存在于c#中。
string content = "This is a message!" + '\0';
这将为您提供一个以null终止符结尾的字符串。 重要的是,null字符是不可见的,不会出现在任何输出中。 它将显示在调试窗口中。 当您将字符串转换为字节数组(用于保存到磁盘和其他IO操作)时,它也会出现,但如果您执行Console.WriteLine(content)
,它将不可见。
您应该理解为什么要使用null终止符,以及为什么要避免使用循环结构来获取所需内容。 除非您最终转换为字节数组,否则空终止字符串在c#中相当无用。 通常,只有在将字符串发送到本机方法,网络或USB设备时才会这样做。
了解如何获取字节也很重要。 在C / C ++中,char存储为1个字节(8位),编码为ANSI。 在C#中,编码是unicode,它是两个字节(16位)。 Jon Skeet的答案向您展示了如何获取unicode中的字节。
舌头在脸颊但可能有用的答案。 如果您在屏幕上以hex输出,则表示您要执行以下两个步骤:
- 将字符串(末尾带有空字符’\ 0’)转换为字节数组
- 转换以hex编码的字节字符串表示
- 交错空间
- 打印到屏幕
试试这个:
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
这是一个经过测试的xml命令的C#示例null终止并且运行良好。
strCmd = @" "; sendB = System.Text.Encoding.UTF8.GetBytes(strCmd+"\0"); sportin.Send = sendB;