C# C中\0终止字符串的帮助#

C# C中\0终止字符串的帮助#,c#,string,cstring,C#,String,Cstring,我正在使用一个低级本机API,在这里我发送一个不安全的字节缓冲区指针来获取一个c字符串值 所以它给了我 // using byte[255] c_str string s = new string(Encoding.ASCII.GetChars(c_str)); // now s == "heresastring\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(etc)"; 所以很明显,我做得不对,我如何去掉多余的?我相信\0在ascii中是“空的”——你确定你得到的字符串实际上

我正在使用一个低级本机API,在这里我发送一个不安全的字节缓冲区指针来获取一个c字符串值

所以它给了我

// using byte[255] c_str
string s = new string(Encoding.ASCII.GetChars(c_str));

// now s == "heresastring\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(etc)";

所以很明显,我做得不对,我如何去掉多余的?

我相信\0在ascii中是“空的”——你确定你得到的字符串实际上是ascii编码的吗?

在转换中可能有一个去掉NUL的选项

除此之外,您可能还可以通过以下方式进行清理:

s = s.Trim('\0');
…或者,如果您认为某些NUL后面可能有非NUL字符,这可能更安全:

int pos = s.IndexOf('\0');  
if (pos >= 0)
    s = s.Substring(0, pos);

.NET字符串不是以null结尾的(您可能已经猜到了)。因此,您可以像对待任何普通字符一样对待“\0”。正常的字符串操作将为您解决问题。这里有一些(但不是全部)选项

如果您确实想在第一个空字符后丢弃任何值,这可能对您更合适。但是要小心,它只适用于实际包含空字符的字符串

s = s.Substring(0, Math.Max(0, s.IndexOf('\0')));

一个
System.Runtime.InteropServices.Marshall.PtrToString*
方法怎么样

Marshal.PtrToStringAnsi
-将第一个空字符之前的所有字符从非托管ANSI字符串复制到托管字符串,并将每个ANSI字符扩展到Unicode


Marshal.PtrToStringUni
-分配托管字符串,并将非托管Unicode字符串的全部或部分复制到其中的第一个null。

最安全的方法是使用:

// s == "heresastring\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(etc)"    
s = s.Split(new[] { '\0' }, 2)[0];
// s == "heresastring"
s = s.Replace("\0", "");

我想他的意思是他得到了一系列空字节,而不是他实际上得到了“\0”字符串序列。我想我会这样做。Trim(“\0”)hahaI在通过RS-232接收字符串时得到了类似的结果。最终我做得不对:我发现处理程序是为接收到的每个字节调用的,在处理程序中,我使用
serialPortInstance.Read(…)
读取了超过1个字节。我不确定,但可能会查看RegularExpression,类似字符串re1=“((?:[a-z][a-z]+)”;获取第一个匹配值以null结尾的字符串的“规则”是,应该忽略以第一个null开头的所有内容。其他几个答案是Trim()或Replace()没有考虑在初始null之后可能会有一些非null的“垃圾”。提供一行解决方案。这些方法忽略了一个事实,即字符串中的第一个空字符之后可能有非空字符。提供了一个更可靠的解决方案。嗯。。。这些方法中的任何一种都是如何在null之后丢失字符的?修剪仅适用于字符串的末端。Replace不会对字符串的任何部分执行任何操作,除了空字符。Split显式保留除空字符以外的所有字符,从而生成字符串数组。看起来每个选项都能安全地处理任何字符串中的每个非空字符。您的解决方案对于OP给出的特定字符串都很有效。但是从本机(C++)API返回的字符串可以在初始null之后包含垃圾。一般解决方案必须忽略初始null之后的所有内容,而不仅仅是忽略null。请在这个示例字符串(“这是一个字符串\0memoryjunkhere”)上尝试您的每个解决方案,以了解我的意思。@Richard:我感谢您尝试澄清这一点,但我的回答并不是简单地复制并放入某人的应用程序的代码。相反,它是为了指出,正常的字符串操作可以很容易地检测并操作空字符。如果开发人员希望保留\0之后的内容,他可以。如果开发人员不想要它,他可以忽略它。OP问题中给出的上下文(“c字符串值”,“去掉多余值”)表明他们希望忽略第一个null之后的所有内容,尽管他们可能还不知道:-)您昨天添加的方法更好,但正如您所提到的,仅当输入字符串至少包含一个null时才有效,这要求调用方实现另一个“if”测试。我在最初的评论中提到的答案(即@MrHIDEn)适用于所有这些场景。太棒了!这是一个单语句回答,可以正确处理从本机(C++)API返回的字符串很可能在第一个null后面包含垃圾非null字符的情况。(例如,“There's a string\0memoryjunkhere”)其他一些答案不能正确处理这一重要场景(或需要IF测试)。这将创建一个临时数组,其中包含每空一个字符串。因此,如果我有一个300 NUL的缓冲区(
\0
),那么在开始处加上“hello”——split将给我一个约294个空字符串的数组。最好使用
s=s.Substring(0,Math.Max(0,s.IndexOf('\0'))我想是方法。@Tomley您忘记了Split()方法的第二个“2”参数。在这种情况下,数组将包含1或2个成员。@Tom Leys此代码将拆分为仅包含2或1个字符串的数组。检查“abc\0\0\0\0”s.Split(新[]{'\0'},2),=>String[“abc”,“\0\0”]它的性能看起来更好,你能给我一个例子吗谢谢。
s = s.Replace("\0", "");