Here is my sample code using .NET Core 6:
using System;
namespace testTerminator
{
class Program
{
static void Main(string[] args)
{
// Given an array of bytes:
byte[] array = {72, 101, 108, 108, 111, 0, 0, 32, 72, 101};
// Converted to a string:
string data = System.Text.Encoding.ASCII.GetString(array);
// Why does the following line not return the position
// of the null characters?
int terminator = data.IndexOf("\0\0"); // returns 0
// Output:
Console.WriteLine("Data is '{0}'", data);
Console.WriteLine("Found terminator at {0}", terminator);
// Verify null characters are still in the data string:
byte[] dataBytes = System.Text.Encoding.ASCII.GetBytes(data);
for (int i = 0; i<dataBytes.Length; i++){
Console.Write("{0},", dataBytes[i]);
}
Console.WriteLine();
}
}
}
This results in the following output:
Data is 'Hello He'
Found terminator at 0
72,101,108,108,111,0,0,32,72,101,
Why does the IndexOf("\0\0") return a zero when the null characters are at position 6?
As noted by @AndrewS in the comments, this is documented by Microsoft. The default is to use the CurrentCulture, and it returns 0 if there is an ignored character for that culture. In .Net 5 the Unicode library was changed, which affected this.
Note that you can reproduce this in a simple one-liner:
Console.WriteLine("abc\0".IndexOf("\0"));
To fix this, you need to use an ordinal comparison
int terminator = data.IndexOf("\0\0", StringComparison.Ordinal); // returns 0
Oddly enough, when you use the char version it doesn't do this
Console.WriteLine("abc\0".IndexOf('\0'));
Returns 3. This is because it does an ordinal comparison by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With