views:

720

answers:

4
  • I am communicating with a server who needs null terminated string
  • How can I do this smartly in C#?
+3  A: 

You add a null character to the end of the string. .NET strings can contain null characters.

Tomalak
Like this "\0" ?
Peter Lillevold
I think he's suggesting 'char c = new char()', which will create the unicode point 'U+0000'.
Steve Cooper
+2  A: 

The strings are already null terminated. Although the string itself doesn't contain a null character, a null character always follows the string in memory.

However, strings in .NET are unicode, so they are stored as UTF-16/UCS-2 in memory, and the server might expect a different encoding, usually an 8 bit encoding. Then you would have to encode the string into a byte array and place a zero byte at the end:

byte[] data = Encoding.Default.GetBytes(theString);
byte[] zdata = new byte[data.Length + 1];
data.CopyTo(zdata, 0);

(The zdata array is all filled with zeroes when creates, so you don't have to actually set the extra byte to zero.)

Guffa
Fixed a minor typo. I'm not too happy with the double buffer allocation personally. You can get around that. Then again, the strings are not likely to be huge or very high volume.
Thorarin
"Null terminated" usually means "ending at the first null". .NET strings cannot be considered to be null-terminated if you also allow that a .NET string may contain one or more null characters and yet not terminate
John Saunders
"The strings are already null terminated. Although the string itself doesn't contain a null character, a null character always follows the string in memory." I've never heard this before, and didn't see any information about this on the MSDN docs. Could you post a source?
Juliet
@John: What I meant specifically with the first sentence is that there is already a terminating zero after the string. If the string itself contains a null character it would naturally not work properly as a null terminated string, but that is a problem that every single answer presented here shares.
Guffa
@Juliet: http://www.yoda.arachsys.com/csharp/strings.html
Guffa
@Guffa: Jon's page seems to conflict directly with the [actual documentation](http://msdn.microsoft.com/en-us/library/ms228362.aspx). I don't think that C# strings are really null-terminated, the marshaling process just knows how to null-terminate them (and I'm not sure how it would preserve embedded nulls, or if that's even possible).
Aaronaught
@Aaronaught: The documentation only says that the string doesn't use a terminating null character, it doesn't say anything about whether a null character is placed after the string in the character array or not.
Guffa
+5  A: 

I assume you're implementing some kind of binary protocol, if the strings are null terminated. Are you using a BinaryWriter?

The default BinaryWriter writes strings as length prefixed. You can change that behavior:

class MyBinaryWriter : BinaryWriter
{
    private Encoding _encoding = Encoding.Default;

    public override void Write(string value)
    {
        byte[] buffer = _encoding.GetBytes(value);
        Write(buffer);
        Write((byte)0);
    }
}

Then you can just write any string like this:

using (MyBinaryWriter writer = new MyBinaryWriter(myStream))
{
    writer.Write("Some string");
}

You may need to adjust the _encoding bit, depending on your needs.

You can of course expand the class with specific needs for other data types you might need to transfer, keeping your actual protocol implementation nice and clean. You'll probably also need your own (very similar) BinaryReader.

Thorarin
+1  A: 

I think the smart way is to do it simply.

string str = "An example string" + char.MinValue; // Add null terminator.

Then convert it into bytes to send to the server.

byte[] buffer = ASCIIEncoding.ASCII.GetBytes(str);

Of course what encoding you use depends on what encoding the server expects.

Fara
char.MinValue is the real C# way to go
PulsarBlow