【问题标题】:C++ : Interpret unicode white spaceC++:解释 unicode 空白
【发布时间】:2017-12-02 12:03:00
【问题描述】:

我有一个包含文本(ASCII + unicode)的文件,我正在尝试使用 C++ 程序计算其中的总字数。要求我应该逐行读取文件(使用getline),然后处理每一行以计算其中的单词。

所以我写了以下简单的程序:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main(int argc, char* argv[]) {
  uint64_t ct = 0;
  std::string line;
  std::ifstream infile(argv[1]);
  while(std::getline(infile, line)) {
    std::stringstream inputStream(line);
    std::string token;
    while (inputStream >> token) {
      ++ct;
    }
  }

  std::cout << ct << std::endl;

  return 0;
}

但是,上述程序输出的数字小于wc -w 命令给出的数字。为了缩小问题的范围,我修改了程序以简单地输出它读取的任何内容。所以现在程序变成了:

int main(int argc, char* argv[]) {
  uint64_t ct = 0;
  std::string line;
  std::ifstream infile(argv[1]);
  while(std::getline(infile, line)) {
    std::stringstream inputStream(line);
    std::string token;
    while (inputStream >> token) {
      std::cout << token << " ";
    }
    std::cout << std::endl;
  }

  return 0;
}

我将此程序的输出重定向到另一个文件。现在,当我在这个新文件上运行wc -w 时,数字与在原始文件上运行wc -w 相同。这意味着,我正在阅读程序中的所有单词(即wc 定义的“单词”)。因此,一个合理的解释是,使用inputStream &gt;&gt; token 读取的token 的值之一包含一些被wc 程序解释为空格的unicode 字符。那么如何更改我的程序以支持对 unicode 空白字符的这种解释呢?

【问题讨论】:

  • 如果没有外部依赖,这并不容易。 Boost 将此实现为一个查找表,以将每个字符映射到给定的类型,然后使用一些启发式方法检查该类型。基本上,您要么需要体面的 Unicode 支持,例如 Boost 或 Qt,要么不必费心。 boost.org/doc/libs/1_62_0/boost/spirit/home/support/…
  • 如果您有兴趣,相关任务是将您的 Unicode 文本转换为 UTF-32(检查是开始字节还是继续字节,或纯 ASCII),检查代码点以查看是否它是使用查找表的空白,然后将其用作标记。如果这听起来很复杂,而且工作量很大,那就是,并且有很多库已经为您完成了这项工作。 Boost 就是其中之一。
  • Unicode 中有很多“空格”字符 - 所以这变成了字符和查找的映射。由于需要针对所有可能带来的乐趣进行测试,因此容易出错。我会说,从高层次来说,C++ 可能不是像这样的字符串操作的最佳语言。
  • @AlexanderHuszagh:我明白了。我可以使用 boost 来完成这项任务。使用 boost 标记字符串的最佳方法是什么?这样做比使用isspace 检查每个字符更容易。
  • @JohnElaine 你的源编码是什么,你能转换成 UTF-32 吗?在 UTF-32 中检查空格是最简单的。基本上,我会逐行获取,转换为 UTF-32,逐个代码点迭代代码点并检查每个代码点是否是空白并逐个处理令牌。这并不漂亮,但它可以很容易做到。如果您不想转换为 UTF-32,您可以在 UTF-8 中逐个字符地查看:如果它是 ASCII 字符(

标签: c++ string unicode


【解决方案1】:

你可以选择:

A. Java's definition of Unicode(非不间断)空格

B. 所有 25 个 Unicode 代码点中的 Wikipedia's list 定义为空格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多