UTF16(例如用于宽winapi函数)字符总是2字节长吗?

Cra*_*ray 5 c++ unicode winapi utf-8 utf-16

请为我澄清一下,UTF16如何工作?考虑到以下几点,我有点困惑:

  • C++中有一个静态类型,WCHAR,长度为2个字节.(总是2个字节长)
  • 大多数msdn和其他一些文档似乎都假设字符总是2个字节长.这可能只是我的想象力,我无法想出任何特定的例子,但它似乎就是这样.
  • 在C++或Windows中没有广泛使用的"超宽"函数或字符类型,因此我假设UTF16是所有需要的.
  • 根据我不确定的知识,unicode有比65535更多的字符,因此他们显然没有2字节的足够空间.
  • UTF16似乎是UTF8的更大版本,UTF8字符可以有不同的长度.

因此,如果一个UTF16字符不总是2个字节长,那么它还能有多长时间?3个字节?或只是2的倍数?再例如,如果有就是想知道在字符的宽字符串的大小WINAPI功能,并且该字符串包含2个字符这是4个字节长,怎么是,字符串的大小以字符计算?

是2个字符长还是4个字符长?(因为它长8个字节,每个WCHAR是2个字节)

更新:现在我看到字符计数不一定是标准的东西或c ++的东西,所以我会尝试在我的第二个问题中更具体一点,关于宽字符串的"字符"的长度:

在Windows上,特别是在Winapi中,在它们的广泛功能(以W结尾)中,如何计算由2个unicode代码点组成的字符串中的字符数,每个代码点由2个代码单元组成(总共8个字节)?这样的字符串是2个字符长(与代码点数相同)还是4个字符长(与codeunits总数相同?)

或者,更通用:"宽字符串中的字符数"的窗口定义是什么意思,代码点的数量或代码单元的数量是多少?

Nat*_*ate 8

简答:不.

一个的尺寸wchar_t-the基本字符单元是没有定义由C++标准(参见第3.9.1节第5段).实际上,在Windows平台上它是两个字节长,在Linux/Mac平台上它是四个字节长.

此外,字符以特定于endian的格式存储.在Windows上,这通常意味着小端,但它也适用于wchar_t包含大端数据.

此外,即使每个wchar_t字节长度为两(或四)个字节,单个字形(粗略地说,一个字符)可能需要多个wchar_ts,并且可能有多种方式来表示它.

一个常见的例子是字符é(LATIN SMALL LETTER E WITH ACUTE),代码点0x00E9.这也可以表示为"分解的"代码点序列0x0065 0x0301(LATIN SMALL LETTER E后面跟着COMBINING ACUTE ACCENT).两者都有效; 有关更多信息,请参阅Wikipedia关于Unicode等效性的文章.

简单地说,您需要知道或选择您将使用的编码.如果处理Windows API,一个简单的选择是假设所有内容都是以2字节wchar_ts 存储的小端UTF-16 .

在Linux/Mac上,UTF-8(带有chars)更常见,API通常采用UTF-8.wchar_t被认为是浪费,因为它每个字符使用4个字节.

因此,对于跨平台编程,您可能希望在内部使用UTF-8并在调用Windows API时即时转换为UTF-16.Windows提供了MultiByteToWideCharWideCharToMultiByte功能做到这一点,你也可以发现,可以简化使用这些功能,如包装ATL和MFC字符串转换宏.

更新

问题已经更新,以询问Windows API在询问字符串中的"字符数"时的含义.

如果API显示"以字符为单位的字符串大小",则它们指的是wchar_ts的数量(char如果由于某种原因在非Unicode模式下进行编译,则为s的数量).在这种特定情况下,您可以忽略Unicode字符可能需要多个字符的事实wchar_t.那些API只是想填充一个缓冲区,需要知道它们有多少空间.


eta*_*ion 5

你似乎有几个误解.

C++中有一个静态类型,WCHAR,长度为2个字节.(总是2个字节长)

这是错的.假设您引用了c ++类型wchar_t- 它并不总是2个字节长,4个字节也是一个公共值,并且没有限制它只能是那两个值.如果你没有引用它,它不是在C++中,而是一些特定于平台的类型.

  • 在C++或Windows中没有广泛使用的"超宽"函数或字符类型,因此我假设UTF16是所有需要的.

  • UTF16似乎是UTF8的更大版本,UTF8字符可以有不同的长度.

UTF-8和UTF-16是相同字符集的不同编码,因此UTF-16不是"更大".从技术上讲,UTF-8中使用的方案可以编码比UTF-16中使用的方案更多的字​​符,但是作为UTF-8和UTF-16,它们编码相同的集合.

在谈到unicode时,不要轻易使用术语"字符".甲codeunit在UTF-16是2个字节宽,一个码点被1个或2 CODEUNITS表示.人们通常理解为"字符"的东西是不同的,可以由一个或多个代码点组成,如果你作为程序员将代码点与字符混淆,可能会出现像http://ideone.com/qV2il这样糟糕的事情.