5

We already have a question about getting the first 16-bit char of a string.

This includes the question code:

MyString.ToCharArray[0]

and accepted answer code:

MyString[0]

I guess there are some uses for that, but when the string contains text we hopefully are all aware that a single 16-bit char cannot hold a character, even in the restricted sense where we actually mean "codepoint".

I am a programmer but not a C# programmer. I am just trying to help an online colleague fix such a bug, in case you feel this is too basic a question.

So if we have a string in C# in a char array, encoded in correct UTF-16, possibly including a surrogate pair as the first character/codepoint and thus potentially consisting of two chars, how do I get that first character?

(I naïvely assume Microsoft provides a string function for this and that I don't have to manually check for surrogate pairs.)

Community
  • 1
  • 1
hippietrail
  • 15,848
  • 18
  • 99
  • 158

2 Answers2

9

You can use StringInfo class which is aware of surrogate pairs and multibyte chars.

        var yourstring = "test"; // First char is multibyte char.
        var firstCharOfString = StringInfo.GetNextTextElement(yourstring,0);
Sameer
  • 3,124
  • 5
  • 30
  • 57
  • I upvoted because it looked right, but now I'm testing it in dotnetfiddle and it's printing "test", not "". If I change it to `si.SubstringByTextElements(0)` it prints "test". – hippietrail Apr 24 '15 at 05:00
  • 1
    @hippietrail code was almost fine - Sameer used wrong override (updated) that returns substring starting from given "element"... You obviously alredy found proper overrid, but linking it here [SubstringByTextElement](https://msdn.microsoft.com/en-us/library/vstudio/6skbbth0%28v=vs.100%29.aspx) for future reference. – Alexei Levenkov Apr 24 '15 at 05:08
  • No I'm lumbering around in the dark here with a flaky connection to dotnetfiddle.net and a flaky connection to MSDN and no knowledge specific to .NET or C# - so thanks! – hippietrail Apr 24 '15 at 05:12
  • 1
    @hippietrail ..Actually I copy pasted the code from my previous answer... and forgot to edit the code to fit it to the context..Edited the code :) – Sameer Apr 24 '15 at 05:15
  • Thanks @Sameer - could you include the relevant `using`s? Here in Vietnam my online resources keep not working this morning and I'm a C# newbie so have to look everything up if it's not handed to me (-: – hippietrail Apr 24 '15 at 05:17
  • Got it! Accepted! It would be good if you guys could look at Iswanto's answer because that doesn't work for me but don't know if it's me doing something wrong testing it. – hippietrail Apr 24 '15 at 05:19
2

Use this:

str = str.Substring(0, 1);

or

str[0];

or

str.FirstOrDefault();
Iswanto San
  • 18,263
  • 13
  • 58
  • 79
  • At least on dotnetfiddle.net, all three of these result in this error: `Run-time exception (line -1): Execution time limit was exceeded Stack Trace: [DotNetFiddle.Infrastructure.LimitExceededException: Execution time limit was exceeded]` – hippietrail Apr 24 '15 at 05:11
  • First option was quick and simple for me – SandstormNick May 09 '20 at 10:26