如何将字符串转换为以空结束的字符串

本文关键字:字符串 结束 转换 | 更新日期: 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格式的字节。

开玩笑,但可能有用的答案。如果您想在屏幕上输出(十六进制),如您所示,您需要遵循两个步骤:

  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 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;