C# byte[] to String showing don't cut after '\0'

11,340

Solution 1

Presumably, you want to remove all chars including and after the first '\0'. Trim will not do this. You need to do something like this:

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

Solution 2

If the array really is ascii (one byte per char), you can find null by searching array for value 0

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

This approach would somewhat optimize the code, not creating strings that contains multiple '/0's

Solution 3

The value of bytesRW is the number of bytes that were copied to the buffer as stated here. The GetString method has an overload that takes a position and a length. If you pass zero as your position and bytesRW as the length it should create a string containing the value you wanted.

Solution 4

You can use LINQ like following code.

Encoding.ASCII.GetString(buffer.TakeWhile(x => x != 0).ToArray());

Solution 5

Based on mortb response, here what I got :

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)

But, the call to Array.IndexOf is different. The second argument have to be a byte, indeed, 0 is an int and can not be found in a byte array.

Share:
11,340
Piotr Łużecki
Author by

Piotr Łużecki

I am lazy javascript developer.

Updated on July 29, 2022

Comments

  • Piotr Łużecki
    Piotr Łużecki almost 2 years

    I'm reading something from memory (in byte array) and then i want to convert it, but result is something like "wanteddata\0\0\0\0\0\0\0\0...". How can i cut it to "wanteddata"? I'm not sure of size that wanteddata will have so i gave maximum size: 14. The way i read from memory and convert:

            String w="";
            ReadProcessMemory(phandle, bAddr, buffer, 14, out bytesRW);
            w = ASCIIEncoding.ASCII.GetString(buffer);
    
  • CodesInChaos
    CodesInChaos about 12 years
    That doesn't really help him, since ReadProcessMemory doesn't simply stop because the end of a cstring was reached. Of course it's good style to check bytesRW, but it doesn't fix his concrete problem.
  • mortb
    mortb about 12 years
    wouldn't it be better to find the first null terminator before he create the string? If the array really is ascii (one byte per char), he can find null by searching array for value 0 String w=""; ReadProcessMemory(phandle, bAddr, buffer, 14, out bytesRW); int nullIdx = Array.IndexOf(buffer, 0); w = ASCIIEncoding.ASCII.GetString(buffer, 0, nullIndex);
  • CodesInChaos
    CodesInChaos about 12 years
    @mortb That's perfectly fine too. How about posting it as an answer?
  • CodesInChaos
    CodesInChaos about 12 years
    You should probably handle the case where nullIdx == -1, like Nicholas does.
  • Derek C.
    Derek C. about 4 years
    While code only answers are allowed, consider adding some explanation to your answer in order to make it more useful in the future.