C# C中字符的返回码点#

C# C中字符的返回码点#,c#,unicode,unicode-string,C#,Unicode,Unicode String,如何返回角色的名称?例如,如果输入为“A”,则输出应为“U+0041”。理想情况下,解决方案应该考虑到这一点 对于代码点,我指的是实际的代码点,它不同于(UTF8有8位代码单元,UTF16有16位代码单元,UTF32有32位代码单元,在后一种情况下,在考虑到endianness后,值等于代码点)。简单,因为C#中的字符实际上是UTF16代码点: char x = 'A'; Console.WriteLine("U+{0:x4}", (int)x); 为了处理注释,C#中的char是一个16位的

如何返回角色的名称?例如,如果输入为“A”,则输出应为“U+0041”。理想情况下,解决方案应该考虑到这一点

对于代码点,我指的是实际的代码点,它不同于(UTF8有8位代码单元,UTF16有16位代码单元,UTF32有32位代码单元,在后一种情况下,在考虑到endianness后,值等于代码点)。

简单,因为C#中的字符实际上是UTF16代码点:

char x = 'A';
Console.WriteLine("U+{0:x4}", (int)x);
为了处理注释,C#中的
char
是一个16位的数字,它包含一个UTF16代码点。位空间大于16的代码点不能用C#字符表示。C#中的字符宽度不可变。但是,一个字符串可以有两个字符相互跟随,每个字符都是一个代码单元,形成一个UTF16代码点。如果您有一个字符串输入和16位以上的字符,您可以使用
char.IsSurrogatePair
char.ConvertToUtf32
,如另一个答案所示:

string input = ....
for(int i = 0 ; i < input.Length ; i += Char.IsSurrogatePair(input,i) ? 2 : 1)
{
    int x = Char.ConvertToUtf32(input, i);
    Console.WriteLine("U+{0:X4}", x);
}
字符串输入=。。。。
对于(int i=0;i
我在上找到了一个小方法。希望这有帮助

    public int get_char_code(char character){ 
        UTF32Encoding encoding = new UTF32Encoding(); 
        byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray()); 
        return BitConverter.ToInt32(bytes, 0); 
    } 

以下代码将
字符串
输入的代码点写入控制台:

string input = "\uD834\uDD61";

for (var i = 0; i < input.Length; i += char.IsSurrogatePair(input, i) ? 2 : 1)
{
    var codepoint = char.ConvertToUtf32(input, i);

    Console.WriteLine("U+{0:X4}", codepoint);
}
string input=“\uD834\uDD61”;
对于(变量i=0;i
输出:

U+1D161 由于.NET中的字符串是UTF-16编码的,因此需要首先将构成字符串的
char
值转换为UTF-32。

C#无法在
char
中存储unicode码点,因为
char
只有2个字节,unicode码点通常超过该长度。解决方案是将代码点表示为字节序列(字节数组或“展平”为32位原语)或字符串。公认的答案转换为UTF32,但这并不总是理想的

这是我们用来将字符串拆分为unicode代码点组件的代码,但保留了本机UTF-16编码。结果是可枚举的,可用于在C#/.NET中本机比较(子)字符串:

public类InvalidEncodingException:System.Exception
{ }
公共静态IEnumerable点(此字符串为s)
{
对于(int i=0;i
事实上@Yogendra Singh的回答有一些优点,目前是唯一投反对票的。 这项工作可以这样做

    public static IEnumerable<int> Utf8ToCodePoints(this string s)
    {
        var utf32Bytes = Encoding.UTF32.GetBytes(s);
        var bytesPerCharInUtf32 = 4;
        Debug.Assert(utf32bytes.Length % bytesPerCharInUtf32 == 0);
        for (int i = 0; i < utf32bytes.Length; i+= bytesPerCharInUtf32)
        {
            yield return BitConverter.ToInt32(utf32bytes, i);
        }
    }
公共静态IEnumerable Utf8ToCodePoints(此字符串为s)
{
var utf32Bytes=Encoding.UTF32.GetBytes;
var bytesPerCharInUtf32=4;
Assert(utf32bytes.Length%bytesPerCharInUtf32==0);
for(int i=0;i
测试


在.NET Core 3.0或更高版本中,您可以使用:


//请注意,它们是unicode代码单位,而不是代码点。那么需要多个代码单位的字符呢?@driis…与GregS相同comment@driis:我没有否决你的意见,我只是想说明一点。@Qaesar小写字母a(
'a'
)是
U+0061
,大写字母a(
'a'
)是
U+0041
如果我们让您感到困惑,很抱歉。问题是Unicode编码实际上有点复杂,尽管乍一看可能不是这样。这个答案中的代码,或者@dtb发布的代码,对您来说很好。如果您需要更多背景,我可以推荐。这是否会返回与
(int)不同的内容字符
?如果
字符
是代理项对的一半,会发生什么?@dtb(我知道答案很晚)。这段代码的有趣之处在于它显示了使用
utf32编码
,但由于该方法只使用
字符
,因此它没有效果,并且与
(int)相同character
,虽然比cast慢得多。事实上,
character.ToString().toCharray()
将始终返回一个项目数组(大小为2字节),而
位转换器
将永远不会返回值>65535。原则上这是一个好主意,但它的呈现方式毫无用处。它不会转换为UTF-32,而是将代码点返回为整数,UTF-32是一种编码,而不是整数。这种命名方法传播了与microsoft将UTF-16LE编码标记为“unicode”一样的混乱“@Esailija:我不确定还有什么更令人困惑:使用名为
ConvertToUtf32
的方法转换为Unicode代码点,或者转换为UTF-32并将结果视为Unicode代码点。你不能把转换成实际UTF-32的结果当作代码点,你需要从编码中解码代码点,就像从UTF-16或UTF-8中解码一样,只是更简单。但我明白为什么这会被视为吹毛求疵:p这个问题措辞严重错误。“返回字符的‘Unicode’”毫无意义,坦率地说,这是胡说八道。你的例子清楚地说明了你真正想要什么,但是标题需要修改。请这样做。@tchrist,谢谢你。。我更新了我的问题谢谢。我对你表示感谢。@Qaesar小写字母a(
'a'
)是
U+0061
,大写字母a(
'a'
)是
U
U+1D161
    public class InvalidEncodingException : System.Exception
    { }

    public static IEnumerable<string> UnicodeCodepoints(this string s)
    {
        for (int i = 0; i < s.Length; ++i)
        {
            if (Char.IsSurrogate(s[i]))
            {
                if (s.Length < i + 2)
                {
                    throw new InvalidEncodingException();
                }
                yield return string.Format("{0}{1}", s[i], s[++i]);
            }
            else
            {
                yield return string.Format("{0}", s[i]);
            }
        }
    }
}
    public static IEnumerable<int> Utf8ToCodePoints(this string s)
    {
        var utf32Bytes = Encoding.UTF32.GetBytes(s);
        var bytesPerCharInUtf32 = 4;
        Debug.Assert(utf32bytes.Length % bytesPerCharInUtf32 == 0);
        for (int i = 0; i < utf32bytes.Length; i+= bytesPerCharInUtf32)
        {
            yield return BitConverter.ToInt32(utf32bytes, i);
        }
    }