Domanda

I have read a question about UTF-8, UTF-16 and UCS-2 and almost all answers give the statement that UCS-2 is obsolete and C# uses UTF-16.

However, all my attempts to create the 4-byte character U+1D11E in C# failed, so I actually think C# uses the UCS-2 subset of UTF-16 only.

There are my tries:

string s = "\u1D11E"; // gives the 2 character string "ᴑE", because \u1D11 is ᴑ
string s = (char) 0x1D11E; // won't compile because of an overflow
string s = Encoding.Unicode.GetString(new byte[] {0xD8, 0x34, 0xDD, 0x1E}); // gives 㓘ờ

Are C# strings really UTF-16 or are they actually UCS-2? If they are UTF-16, how would I get the violin clef into my C# string?

È stato utile?

Soluzione

Use capital U instead:

  string s = "\U0001D11E";

And you overlooked that most machines are little-endian:

  string t = Encoding.Unicode.GetString(new byte[] { 0x34, 0xD8, 0x1E, 0xDD });

Altri suggerimenti

C# definitely uses UTF-16. The correct way to define characters above the U+0000 - U+FFFF range is using the escape sequence that permits defining characters using 8 hex digits:

string s = "\U0001D11E";

If you use \u1D11E it's interpreted as the U+1D11 character followed by an E.

One thing to keep in mind when using these characters is that the String.Length property and most string methods work on UTF-16 code units, not Unicode characters. From MSDN documentation:

The Length property returns the number of Char objects in this instance, not the number of Unicode characters. The reason is that a Unicode character might be represented by more than one Char. Use the System.Globalization.StringInfo class to work with each Unicode character instead of each Char.

According to the C# specification, characters of more than 4 hex characters' length are encoded using \U (uppercase U) and 8 hexadecimal characters. Once encoded correctly in the string, it can be correctly exported using any unicode encoding;

string s = "\U0001D11E";

foreach (var b in Encoding.UTF32.GetBytes(s))
    Console.WriteLine(b.ToString("x2"));

Console.WriteLine();

foreach (var b in Encoding.Unicode.GetBytes(s))
    Console.WriteLine(b.ToString("x2"));

> 1e
> d1
> 01
> 00
>
> 34
> d8
> 1e
> dd
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top