如何将字符串转换为以空结束的字符串
本文关键字:字符串 结束 转换 | 更新日期: 2023-09-27 18:08:41
如何将简单字符串转换为以空结尾的字符串?
例子:
示例字符串:"Test message"
以下是字节:
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
我可以使用循环,但是代码太丑了。如何通过本机方法进行这种转换?
看起来您想要一个以空结束的Unicode字符串。如果字符串存储在一个变量str
中,这应该可以工作:
var bytes = System.Text.Encoding.Unicode.GetBytes(str + "'0");
(看它运行)
请注意,结果数组的末尾将有三个零字节。这是因为Unicode使用两个字节表示字符。第一个零是原始字符串中最后一个字符的一半,后面两个是Unicode对空字符''0'
的编码方式。(换句话说,使用我的代码比您最初指定的多了一个空字符,但这可能是您实际想要的。)
c#字符串的一些背景知识是一个很好的开始。
c#字符串的内部结构与C字符串不同。a)它是unicode,就像'char'一样b)非null终止c)它包含了许多在c/c++中你需要的实用函数。
它是如何摆脱没有null终止的?简单!c# String在内部管理一个字符数组。c#数组是结构体,而不是指针(与C/c++不同)。因此,它们知道自己的长度。C/c++中的Null终止是必需的,以便字符串实用程序函数(如strcmp())能够在内存中检测字符串的结束。
null字符在c#中确实存在。
string content = "This is a message!" + ''0';
这将给你一个以空结束符结束的字符串。重要的是,null字符是不可见的,不会出现在任何输出中。它将显示在调试窗口中。当您将字符串转换为字节数组(用于保存到磁盘和其他IO操作)时,它也会出现,但如果您使用Console.WriteLine(content)
,它将不可见。
你应该明白为什么你想要空终止符,为什么你想避免使用循环结构来获得你想要的东西。以空结尾的字符串在c#中是相当无用的,除非你最终要转换成字节数组。一般来说,只有当你想通过网络或usb设备将字符串发送给本机方法时,你才会这样做。
了解如何获取字节也很重要。在C/c++中,一个字符被存储为1字节(8位),编码是ANSI。在c#中,编码是unicode,它是两个字节(16位)。Jon Skeet的答案向您展示了如何获得unicode格式的字节。
开玩笑,但可能有用的答案。如果您想在屏幕上输出(十六进制),如您所示,您需要遵循两个步骤:
- 将字符串(末尾为空字符''0')转换为字节数组
- 转换十六进制编码的字节字符串表示
- 与空格交错
- 打印到屏幕
试试这个:
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 00
这是一个经过测试的c#示例,xml命令以null终止,效果很好。
strCmd = @"<?xml version=""1.0"" encoding=""utf-8""?><Command name=""SerialNumber"" />";
sendB = System.Text.Encoding.UTF8.GetBytes(strCmd+"'0");
sportin.Send = sendB;