【问题标题】:Find length in characters of a std::wstring查找 std::wstring 的字符长度
【发布时间】:2011-08-21 08:52:56
【问题描述】:

我正在使用 std::wstring 变量(C++ 语言)& 我正在尝试确定字符串的长度(以字符为单位)。

函数 .length 和 .size() 给出的结果不是字符长度(我想他们告诉我有多少个宽字符?)。

那么有没有办法确定 wstring 的字符长度?

【问题讨论】:

  • 我怀疑你真的需要这样做。请参阅字形、字符、代码点、代码单元的definitions。可能您的意思是代码点,但几乎可以肯定它不是很有用。
  • std::wstring length的可能重复

标签: c++ unicode


【解决方案1】:

“字符”是什么意思?

std::basic_string 只是一系列值的容器,我们将其视为字符串。它不关心值在什么 encoding 中;它所做的只是存储和管理有序的值序列。因此,sizelength 函数说明了它存储了多少值。

如果您的 std::wstring 包含一个字符串,例如,一个有效的 UTF-16 编码字符串,std::wstring 不在乎。 Unicode 编码只是编码代码点的方法。 UTF-16 使用 16 位代码单元对其代码点进行编码,其中可以包括对应于单个 Unicode 代码点的 16 位值的代理对。

但是,根据该术语的某些定义,Unicode 代码点不是“字符”。例如,有组合代码点,其中多个代码点组合成一个字形。有不可见的代码点(控制代码等)。

如果您想知道std::wstring 中有多少个代码点,那么您必须使用可以处理 UTF-16 数据的函数遍历该字符串。如果您想知道字符串中有多少 graphemes(逻辑字形),那么您需要使用更复杂的算法来遍历它。

【讨论】:

  • 需要注意的一点,std::wstring 不一定包含 UTF-16 数据(这取决于平台和环境)。
【解决方案2】:

为此,您必须使用 Unicode 数据库。您应该使用 ICU (how to do it in ICU) 或其他一些 Unicode 库。 Boost.Locale 已经被接受为 boost 并将很快推出,它以一种很好的方式包装了 ICU 的一些功能。

但是,我怀疑您是否真的需要这样做。见definitions of grapheme, character, codepoint, codeunit。可能您的意思是代码点,但几乎可以肯定它不是很有用。

【讨论】:

    【解决方案3】:

    根据您的字符串的来源,您可能无法任何控制它的含义,即它的编码方式。要将您的字符串转换为明确的语义,您可能需要执行以下步骤:

    1. 通过argvgetenv 从环境中读取字节串。这是一个字节字符串,具有平台和语言环境相关的编码。

    2. 通过mbstowcs() 将字节字符串转换为内部固定宽度(有警告)宽字符串。 你仍然不知道结果的编码!你所知道的是每个宽字符都足够大以容纳任何“平台的字符值”,无论这意味着什么。 (在 Windows 中,它意味着 broken)。

    3. 通过使用 ICU 或 iconv() 将 WCHAR 转换为 UCS-4/UTF-32,获取 Unicode 代码点序列(即,您可以按代码点操作的确定数据)。现在你知道你在处理什么了!

    如果您正在从具有文档化编码的文件或网络中读取数据,您应该将文档化文件编码转换为 UCS-4。

    一旦您获得了一系列代码点,对文本处理的低级语言支持就结束了。一系列代码点是在二进制级别上表示文本的最佳方式。任何更高级别的文本操作和处理都是复杂而微妙的,并且在很大程度上取决于对“文本”的正确定义,因此最好将其留给专用的 Unicode 库(例如 ICU)。在编程语言级别,“字符”是代码点,但在任何严肃的应用程序中,这可能不是您想要的,您想了解字素和规范化以及其他一百件小事。

    【讨论】:

      【解决方案4】:

      您在寻找 wcslen 吗?

      #include <wchar.h>
      size_t wcslen(const wchar_t *s);
      

      【讨论】:

      • 他不是。 wcslen.size()wstring 相同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 2013-05-03
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多