Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# convert byte[] containing a c-style string to string - NOT Encoding.GetString(byte[])

Tags:

string

c#

stupid me tries to convert a byte-array received from an external source not unter my control to a string. (And yes, I do know about Encoding.GetString(byte[]).

What I have so far:

void myfunc()
{
    byte[] rawData = new byte[ 128 ];

    for( int i = 0; i < rawData.Length; ++i )
    {
        rawData[ i ] = 0;
    }

    rawData[ 0 ] = (byte)'H';
    rawData[ 1 ] = (byte)'e';
    rawData[ 2 ] = (byte)'l';
    rawData[ 3 ] = (byte)'l';
    rawData[ 4 ] = (byte)'o';


    string asString = Encoding.UTF8.GetString( rawData, 0, rawData.Length );

    string asRealString = Encoding.UTF8.GetString( rawData );
}

Both strings do contain the Hello part but also a lot of \0's afterwards - which is not the thing I expected. The output from the debugger: asRealString =

"Hello\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"

Is there any way that would geive me a string like "Hello" ?

I did goolge,but all I got was Encoding.GetString(byte[]) ...

EDIT: The creatin of the byte array is outside my scope! I do get it as part of a larger, C-Style struct. And there is no leading length of the string. Also I was hoping there iss ome built in way to tdo it and I did not have to find the first \o and tehn convert knowing the length....

EDIT Here is what I used in the end:

private static string convertCString( byte[] buffer, int maxLength, Encoding targetEncoding )
{
    int length = 0;
    int realMax = buffer.Length < maxLength ? buffer.Length : maxLength;

    for( 
         ; 0 != buffer[length] && length < realMax
         ; ++length )
    {}

    return targetEncoding.GetString( buffer, 0, length );
}
like image 560
Mario The Spoon Avatar asked May 11 '11 13:05

Mario The Spoon


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


3 Answers

Just find the first 0:

    int len = Array.IndexOf(rawData, (byte)0); // maybe some bounds check too
    string asString = Encoding.UTF8.GetString(rawData, 0, len);
like image 129
Marc Gravell Avatar answered Oct 14 '22 23:10

Marc Gravell


Try

Encoding.UTF8.GetString( rawData ).Trim();
like image 37
Aliostad Avatar answered Oct 14 '22 22:10

Aliostad


The creatin of the byte array is outside my scope! I do get it as part of a larger, C-Style struct. And there is no leading length of the string.

It may be possible to do this in a built-in way by having the marshaller do it for you.

I'm assuming that what you have now is like:

struct CStruct
{
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)]
  public byte[] data;
}

Try changing it to:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct CStruct
{
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
  public string data;
}
like image 23
Stephen Cleary Avatar answered Oct 14 '22 21:10

Stephen Cleary