Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建包含代理项对的字符串?_C#_String_Utf 16_Utf 32_Surrogate Pairs - Fatal编程技术网

C# 如何创建包含代理项对的字符串?

C# 如何创建包含代理项对的字符串?,c#,string,utf-16,utf-32,surrogate-pairs,C#,String,Utf 16,Utf 32,Surrogate Pairs,我在Jon Skeet的博客上看到他谈到了字符串反转。我想尝试一下他给我自己展示的例子,但它似乎奏效了。。。这让我相信,我不知道如何创建一个包含代理项对的字符串,该代理项对实际上会导致字符串反转失败。实际上,如何创建一个包含代理项对的字符串,以便我自己可以看到故障?术语“代理项对”指的是在UTF-16编码方案中使用高代码点编码Unicode字符的一种方法(有关更多信息,请参阅) 在Unicode字符编码中,字符映射到0x000000和0x10FFFF之间的值。在内部,使用UTF-16编码方案来存

我在Jon Skeet的博客上看到他谈到了字符串反转。我想尝试一下他给我自己展示的例子,但它似乎奏效了。。。这让我相信,我不知道如何创建一个包含代理项对的字符串,该代理项对实际上会导致字符串反转失败。实际上,如何创建一个包含代理项对的字符串,以便我自己可以看到故障?

术语“代理项对”指的是在
UTF-16
编码方案中使用高代码点编码Unicode字符的一种方法(有关更多信息,请参阅)

Unicode
字符编码中,字符映射到
0x000000
0x10FFFF
之间的值。在内部,使用
UTF-16
编码方案来存储
Unicode
文本字符串,其中考虑了两个字节(
16位
)的代码序列。由于两个字节只能包含从
0x0000
0xFFFF
的字符范围,因此在存储该范围以上的值时会使用一些额外的复杂性(
0x010000
0x10FFFF

这是使用称为代理的成对代码点来完成的。代理项字符分为两个不同的范围,即
低代理项
高代理项
,这取决于它们是允许出现在两个代码序列的开头还是结尾

你自己试试这个:

String surrogate = "abc" + Char.ConvertFromUtf32(Int32.Parse("2A601", NumberStyles.HexNumber)) + "def";

Char[] surrogateArray = surrogate.ToCharArray();
Array.Reverse(surrogateArray);

String surrogateReversed = new String(surrogateArray);
或者,如果您想继续使用博客示例:

String surrogate = "Les Mise" + Char.ConvertFromUtf32(Int32.Parse("0301", NumberStyles.HexNumber)) + "rables";

Char[] surrogateArray = surrogate.ToCharArray();
Array.Reverse(surrogateArray);

String surrogateReversed = new String(surrogateArray);

nnd然后使用调试器检查字符串值。乔恩·斯基特是对的。。。字符串和日期似乎很简单,但它们绝对不是。

最简单的方法是使用
\U#######
,其中
U
是大写,而
正好表示八个十六进制数字。如果该值超过十六进制
0000FFFF

string myString = "In the game of mahjong \U0001F01C denotes the Four of circles";
您可以检查
myString.Length
以查看一个Unicode字符是否占用两个.NET
Char
值。请注意,
char
类型有两个
static
方法,可以帮助您确定
char
是否是代理项对的一部分

如果您使用的.NET语言没有类似于
\U#######
转义序列的内容,则可以使用方法
ConvertFromUtf32
,例如:

string fourCircles = char.ConvertFromUtf32(0x1F01C);
另外:如果您的C#源文件的编码允许使用所有Unicode字符,如UTF-8,您可以直接将字符放入文件中(通过复制粘贴)。例如:

string fourCircles = char.ConvertFromUtf32(0x1F01C);

string myString=“在麻将游戏中,有趣的是,该示例完全如LinqPad中所述显示,但不是在Visual Studio控制台应用程序中显示。在C中,您可以编写一个十六进制
Int32
值,如下所示:
0x2A601
,因此无需使用
Int32.Parse
NumberStyles
。但是您也可以说
“\U0002A601”
来获取Unicode字符。看到我的答案了。关于“Les Misérables”,还有另一种分解它的方法:
string subrogate=“Les Misérables”。Normalize(NormalizationForm.FormD)堆栈溢出软件正确处理您的麻将字符,我将其复制粘贴到编辑器中,它显示utf-8序列0xF0 0x9F 0x80 0x9C,这是一个4字节的序列,并对unicode代码点0x1F01C进行编码,它是十进制127004,这确实是“麻将牌四圈”代码点。但可能(正如我所做的)我们看不到字符,因为字体不包含字形,所以会显示替换字形/字符。@brighty是的,堆栈溢出似乎可以完美地处理平面0之外的字符。缺少字体或web浏览器支持(旧浏览器)可能会导致问题。由于“有一些静态方法可以帮助您确定字符是否是代理项对的一部分”,我找到了
char.IsSurrogate(myString[I])
,并且能够以非常简单可靠的方式正确识别代理项对。