【问题标题】:To which character encoding (Unicode version) set does a char object correspond?char 对象对应于哪个字符编码(Unicode 版本)集?
【发布时间】:2011-09-26 19:16:23
【问题描述】:

char 对象对应的 Unicode 字符编码在:

  • C#

  • Java

  • JavaScript(我知道实际上没有 char 类型,但我假设 String 类型仍然作为 Unicode 字符数组实现)

一般来说,编程语言之间是否有使用特定字符编码的通用约定?

更新

  1. 我试图澄清我的问题。我所做的更改将在下面的 cmets 中讨论。
  2. Re:“你想解决什么问题?”,我对从语言无关的表达式生成代码感兴趣,并且文件的特定编码是相关的。

【问题讨论】:

  • 不要将字符集与字符编码混淆。有一个 Unicode 字符集(忽略对 Unicode 标准的修订),这意味着一组已定义的字符,但有许多编码,如 UTF-16 和 UTF-8。
  • 您想解决什么问题,在使用这些语言的软件之间交换数据?
  • 这个问题被打破了。没有“unicode 字符集”的选择,只有 unicode 字符集,它是具有定义语义的数字的抽象集合。
  • 您的实际问题或意图是什么?这将有助于提供一个匹配的答案,实际上有助于解决您的问题。
  • @kerreksb, @gatkin - 我已经更新了我的问题。我使用“字符集”来指代“字符编码”。由于 HTTP 内容类型 charset 参数,我感到很困惑。这个公式更合适/更准确吗?

标签: c# java unicode character-encoding char


【解决方案1】:

我不确定我是否在回答你的问题,但让我说几句希望能有所启发的评论。

在核心,像我们正在讨论的那些通用编程语言(C、C++、C#、Java、PHP)没有“文本”的概念,而只有“数据”的概念。数据由整数值序列(即数字)组成。这些数字背后没有内在的含义

将数字流转化为文本的过程是一种语义,通常留给消费者将相关语义分配给数据流。

警告:我现在将使用“编码”这个词,不幸的是它有多个不等价的含义。 “编码”的第一个含义是将含义分配给数字。数字的语义解释也称为“字符”。例如,在 ASCII 编码中,32 表示“空格”,65 表示“大写字母 A”。 ASCII 只为 128 个数字赋予含义,因此每个 ASCII 字符 都可以方便地用一个 8 位字节(最高位始终为 0)来表示。有许多编码将字符分配给 256 个数字,因此每个字符都使用一个字节。在这些固定宽度的编码中,一个文本字符串的字符数与它表示的字节数一样多。还有其他编码,其中字符采用可变数量的字节来表示。

现在,Unicode 也是一种编码,即为数字分配意义。在前 128 个数字上,它与 ASCII 相同,但它为(理论上)2^21 个数字分配了含义。因为有很多含义不是严格意义上的书写意义上的“字符”(例如零宽度连接符或变音符号修饰符),所以术语“代码点”优于“字符”。尽管如此,任何至少 21 位宽的整数数据类型都可以表示一个代码点。通常会选择 32 位类型,并且这种编码(其中每个元素代表一个代码点)称为 UTF-32 或 UCS-4。

现在我们有了“编码”的第二个含义:我可以将一串 Unicode 码点转换成一个 8 位或 16 位值的字符串,从而进一步“编码”信息。在这种新的转换形式(称为“unicode 转换格式”或“UTF”)中,我们现在有 8 位或 16 位值的字符串(称为“代码单元”),但每个单独的值通常不对应任何有意义的东西——它首先必须被解码成一系列 Unicode 代码点。

因此,从编程的角度来看,如果您想修改 文本(不是字节),那么您应该将您的文本存储为 Unicode 代码点序列。实际上,这意味着您需要 32 位数据类型。 C 和 C++ 中的 char 数据类型通常是 8 位宽(尽管这只是最小值),而在 C# 和 Java 中它总是 16 位宽。一个 8 位 char 可以用来存储 transformed UTF-8 字符串,而 16 位 char 可以存储一个 transformed UTF-16 字符串,但是为了要获得原始的、有意义的 Unicode 代码点(尤其是代码点中字符串的长度),您将始终需要执行解码。

通常,您的文本处理库将能够为您进行解码和编码,因此它们会很乐意接受 UTF8 和 UTF16 字符串(但要付出代价),但如果您想省去这种额外的间接性,请存储您的字符串作为足够宽类型的原始 Unicode 代码点。

【讨论】:

  • 最后两段正是我所需要的。谢谢。
  • 很高兴我能帮上忙。我不了解 C# 和 Java,但是在 PHP/Posix/C/C++ 中,您可以利用出色的 iconv 库来执行所有必要的编码和解码。
  • .NET 有 System.Text 命名空间。
【解决方案2】:

C#Java 中是UTF-16

【讨论】:

  • 对于 Java,您可以在 java.lang.Character 类的 API 文档中找到相关信息。
  • @leonbloy:是的,尽管还不清楚 OP 到底想知道什么。他们是在谈论字符集、编码、平面还是其他东西?
  • 这不是问题的真正答案,但问题已经被打破了。
  • 我反对指令“将您的字符串存储为原始 Unicode”。 Unicode 代码点仍然可以包含“间接”——比如字符组合。仍然需要专门的图书馆。较大的字符串(对于大多数语言)将需要更长的时间来处理,因为需要更多的内存*来存储它们(4 倍的字符串需要 4 倍的时间从 RAM 加载到处理器)。 *适用于欧美语言
【解决方案3】:

在 Java 中:

char 数据类型是单个 16 位 Unicode 字符。

取自http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

在 C# 中:

单个 Unicode 字符

取自http://msdn.microsoft.com/en-us/library/ms228360(v=vs.80).aspx

【讨论】:

  • 至少这里的Java语句似乎是从Unicode还是16位字符集的时候开始的。现在它是一个 UTF-16 代码单元,它要么是基本多语言平面中的一个字符,要么是一个代理项(例如,半个代理项对)。 (我想在 C# 中是类似的。)
  • 短语“单个 16 位 unicode 字符”本身就是一个矛盾。首先,它应该是“unicode codepoint”。其次,并非每个代码点都适合 16 位,并且要以 16 位代码单位表示非 BMP 代码点,您必须使用代理对。但是,完全可以将单个代理寡妇存储在 Java char 中,并且可以存储对未分配给任何代码点的值进行编码的代理对。 基本数据类型只存储没有隐含语义的数字。
猜你喜欢
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多