为什么该字符串的长度比其中的字符数长?

2024-05-14

这段代码:

string a = "abc";
string b = "A????C";
Console.WriteLine("Length a = {0}", a.Length);
Console.WriteLine("Length b = {0}", b.Length);

outputs:

Length a = 3
Length b = 4

为什么?我唯一能想象的是汉字有2个字节长并且.Length方法返回字节数。


其他人都给出了表面答案,但也有更深层次的理由:“字符”的数量是一个难以定义的问题,并且计算起来可能会非常昂贵,而长度属性应该很快。

为什么很难定义?嗯,有几个选项,但没有一个比另一个更有效:

  • 代码单元的数量(字节或其他固定大小的数据块;C# 和 Windows 通常使用 UTF-16,因此它返回两字节块的数量)当然是相关的,因为计算机仍然需要处理这种形式的数据出于多种目的(例如写入文件,关心字节而不是字符)

  • Unicode 代码点的数量相当容易计算(尽管是 O(n),因为您必须扫描字符串中的代理项对)并且可能对文本编辑器很重要......但实际上与字符数不同打印在屏幕上(称为字素)。例如,某些带重音的字母可以用两种形式表示:单个代码点或配对在一起的两个点,一个表示字母,另一个表示“为我的伙伴字母添加重音”。这对是两个角色还是一个?您可以规范化字符串来帮助解决此问题,但并非所有有效字母都具有单个代码点表示形式。

  • 即使字素的数量也与打印字符串的长度不同,这取决于字体等因素,并且由于某些字符在许多字体中打印时有一些重叠(字距调整),因此屏幕上字符串的长度无论如何不一定等于字素长度之和!

  • 有些 Unicode 点甚至不是传统意义上的字符,而是某种控制标记。就像字节顺序标记或从右到左指示符一样。这些算不算?

简而言之,字符串的长度实际上是一个极其复杂的问题,计算它会花费大量的 CPU 时间和数据表。

而且,还有什么意义呢?为什么这些指标很重要?好吧,只有你可以根据你的情况回答这个问题,但就我个人而言,我发现它们通常是无关紧要的。我发现限制数据输入更符合逻辑,通过字节限制来完成,因为无论如何这都是需要传输或存储的。限制显示尺寸最好由显示端软件来完成 - 如果消息有 100 个像素,则适合的字符数取决于字体等,而数据层软件无论如何都不知道这些。最后,考虑到 unicode 标准的复杂性,如果您尝试其他方法,无论如何您都可能会在边缘情况下遇到错误。

所以这是一个很难的问题,没有太多通用用途。代码单元的数量很容易计算 - 它只是底层数据数组的长度 - 并且作为一般规则最有意义/有用,具有简单的定义。

这就是为什么b有长度4超出了“因为文档是这么说的”的表面解释。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么该字符串的长度比其中的字符数长? 的相关文章

随机推荐