C#字节数组转换为字符串时,如何避免在'\0'之后截断显示问题。

8

我正在从内存中读取一些东西(以字节数组的形式),然后我想要将其转换,但结果是类似于“wanteddata\0\0\0\0\0\0\0\0…”。我该如何将其截断为“wanteddata”?我不确定所需数据的大小,因此我给出了最大大小:14。我从内存中读取并转换的方式:

        String w="";
        ReadProcessMemory(phandle, bAddr, buffer, 14, out bytesRW);
        w = ASCIIEncoding.ASCII.GetString(buffer);

2
C#不是C语言 - \0不是字符串终止符。 - Oded
你还应该验证一下你的源代码是否真的是ASCII格式,或者ANSI或UTF8才是正确的选择。 - CodesInChaos
5个回答

12

你可能想要移除第一个'\0'字符及其之后的所有字符。但是Trim方法并不能做到这一点。你需要像这样做:

int i = w.IndexOf( '\0' );
if ( i >= 0 ) w = w.Substring( 0, i );

在创建字符串之前找到第一个空终止符不是更好吗?如果数组确实是ASCII(每个字符一个字节),可以通过搜索值为0的数组来找到null。String w = ""; ReadProcessMemory(phandle, bAddr, buffer, 14, out bytesRW); int nullIdx = Array.IndexOf(buffer, 0); w = ASCIIEncoding.ASCII.GetString(buffer, 0, nullIndex); - mortb
@mortb,那也完全没问题。把它发布为答案怎么样? - CodesInChaos

5
如果该数组确实是ascii码(每个字符一个字节),你可以通过搜索数组中的值0来找到null。
String w="";
ReadProcessMemory(phandle, bAddr, buffer, 14, out bytesRW);
int nullIdx = Array.IndexOf(buffer, (byte)0);
nullIdx = nullIdx >= 0 ? nullIdx : buffer.Length;
w = ASCIIEncoding.ASCII.GetString(buffer, 0, nullIndex);

这种方法可以优化代码,避免创建包含多个 '/0' 的字符串。

你应该像Nicholas一样处理nullIdx == -1的情况。 - CodesInChaos

3
你可以像下面的代码一样使用LINQ。
Encoding.ASCII.GetString(buffer.TakeWhile(x => x != 0).ToArray());

1
虽然只有代码答案是允许的,但考虑添加一些解释来使您的答案在未来更有用。 - Derek C.

2

bytesRW的值是指将数据复制到缓冲区中的字节数,详见此处。GetString方法有一个重载,可以传入位置和长度参数。如果您将位置参数设置为0,长度参数设置为bytesRW,则可以创建一个包含所需值的字符串。


这并没有真正帮助他,因为ReadProcessMemory不会仅仅因为到达cstring的结尾而停止。当然,检查bytesRW是好的编程风格,但它并不能解决他具体的问题。 - CodesInChaos

2
根据mortb的回复,我得到以下信息:
public static class EncodingEx
{
    /// <summary>
    /// Convert a C char* to <see cref="string"/>.
    /// </summary>
    /// <param name="encoding">C char* encoding.</param>
    /// <param name="cString">C char* to convert.</param>
    /// <returns>The converted <see cref="string"/>.</returns>
    public static string ReadCString(this Encoding encoding, byte[] cString)
    {
        var nullIndex = Array.IndexOf(cString, (byte) 0);
        nullIndex = (nullIndex == -1) ? cString.Length : nullIndex;
        return encoding.GetString(cString, 0, nullIndex);
    }
}

...

// A call
Encoding.ASCII.ReadCString(buffer)

但是,对Array.IndexOf的调用是不同的。 第二个参数必须是一个byte,实际上,0是一个int,不能在byte数组中找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接