How to convert string to null-terminated one?

13,119

Solution 1

It looks like you want a null-terminated Unicode string. If the string is stored in a variable str, this should work:

var bytes = System.Text.Encoding.Unicode.GetBytes(str + "\0");

(See it run.)

Note that the resulting array will have three zero bytes at the end. This is because Unicode represents characters using two bytes. The first zero is half of the last character in the original string, and the next two are how Unicode encodes the null character '\0'. (In other words, there is one extra null character using my code than what you originally specified, but this is probably what you actually want.)

Solution 2

A little background on c# strings is a good place to start.

The internal structure of a C# string is different from a C string. a) It is unicode, as is a 'char' b) It is not null terminated c) It includes many utility functions that in C/C++ you would require for.

How does it get away with no null termination? Simple! Internally a C# String manages a char array. C# arrays are structures, not pointers (as in C/C++). As such, they are aware of their own length. The Null termination in C/C++ is required so that string utility functions like strcmp() are able to detect the end of the string in memory.

The null character does exist in c#.

string content = "This is a message!" + '\0';

This will give you a string that ends with a null terminator. Importantly, the null character is invisible and will not show up in any output. It will show in the debug windows. It will also be present when you convert the string to a byte array (for saving to disk and other IO operations) but if you do Console.WriteLine(content) it will not be visible.

You should understand why you want that null terminator, and why you want to avoid using a loop construct to get what you are after. A null terminated string is fairly useless in c# unless you end up converting to a byte array. Generally you will only do that if you want to send your string to a native method, over a network or to a usb device.

It is also important to be aware of how you are getting your bytes. In C/C++, a char is stored as 1 bytes (8bit) and the encoding is ANSI. In C# the encoding is unicode, it is two bytes (16bit). Jon Skeet's answer shows you how to get the bytes in unicode.

Solution 3

Tongue in cheek but potentially useful answer. If you are after output on your screen in hex as you have shown there you want to follow two steps:

  1. Convert string (with null character '\0' on the end) to byte array
  2. Convert bytes strings representations encoded in hex
  3. Interleave with spaces
  4. Print to screen

Try this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace stringlulz
{
    class Program
    {
        static void Main(string[] args)
        {
            string original = "Test message";

            byte[] bytes = System.Text.Encoding.Unicode.GetBytes(original + '\0');

            var output = bytes.Aggregate(new StringBuilder(), (s, p) => s.Append(p.ToString("x2") + ' '), s => { s.Length--; return s; });


            Console.WriteLine(output.ToString().ToUpper());
            Console.ReadLine();
        }
    }
}

The output is:

54 00 65 00 73 00 74 00 20 00 6D 00 65 00 73 00 73 00 61 00 67 00 65 00 00 00

Share:
13,119
user2264990
Author by

user2264990

Updated on June 29, 2022

Comments

  • user2264990
    user2264990 almost 2 years

    How to convert a simple string to a null-terminated one?

    Example:

    Example string: "Test message"
    Here are the bytes:

    54 65 73 74 20 6D 65 73 73 61 67 65
    

    I need string with bytes like follows:

    54 00 65 00 73 00 74 00 20 00 6D 00 65 00 73 00 73 00 61 00 67 00 65 00 00
    

    I could use loops, but will be too ugly code. How can I make this conversion by native methods?