C++ 中的 Utf-8:快速而肮脏的技巧

2024-03-19

我知道有关于 utf-8 的各种问题,主要是关于操作 utf-8 “字符串”之类对象的库。

然而,我正在开发一个“国际化”项目(一个网站,我在其中编写了 c++ 后端...不要问),即使我们处理 utf-8,我们实际上也不需要这样的库。大多数时候,简单的 std::string 方法或 STL 算法就足以满足我们的需求,实际上这就是使用 utf-8 的首要目标。

所以,我在这里寻找的是大写“又快又脏”您知道的与存储为 std::string 的 utf-8 相关的技巧(没有 const char*,我真的不关心 C 风格代码,我有更好的事情要做,而不是不断担心我的缓冲区大小) 。

例如,这里有一个“又快又脏”获取字符数的技巧(这对于知道它是否适合您的显示框很有用):

#include <string>
#include <algorithm>

// Let's remember than in utf-8 encoding, a character may be
// 1 byte: '0.......'
// 2 bytes: '110.....' '10......'
// 3 bytes: '1110....' '10......' '10......'
// 4 bytes: '11110...' '10......' '10......' '10......'
// Therefore '10......' is not the beginning of a character ;)

const unsigned char mask = 0xC0;
const unsigned char notUtf8Begin = 0x80;

struct Utf8Begin
{
  bool operator(char c) const { return (c & mask) != notUtf8Begin; }
};

// Let's count
size_t countUtf8Characters(const std::string& s)
{
  return std::count_if(s.begin(), s.end(), Utf8Begin());
}

事实上,当我需要字符数以外的任何内容时,我还没有遇到过这样的用例,并且 std::string 或 STL 算法不免费提供,因为:

  • 排序按预期进行
  • 单词的任何部分都不能与一个单词或另一个单词的一部分混淆

我想知道您是否还有其他类似的技巧,无论是用于计数还是用于其他简单的任务。
我再说一遍,我知道ICU http://site.icu-project.org/ and Utf8-CPP http://utfcpp.sourceforge.net/,但我对它们不感兴趣,因为我不需要成熟的处理(事实上我从来不需要比字符数更多的处理)。
我还重复一遍,我对处理 char* 不感兴趣,它们已经过时了。


好吧,这个肮脏的伎俩是行不通的。 首先,在此之后 mask 的值是多少:

   const unsigned char mask = 0x11000000;
   const unsigned char notUtf8Begin = 0x10000000;

也许您正在将十六进制表示与二进制混合。

其次,正如您在 utf-8 编码中正确所说的那样,一个字符可能有几个字节长。 std::count_if 将迭代 UTF8 序列中的所有字节。 但您实际需要的是查看每个字符的前导字节并跳过其余字节,直到下一个字符出现。

实现执行计算和跳跃的单个循环并不困难 使用简单掩码表作为前导字节。

最后,您将获得相同的 O(n) 来检查字符,并且它将适用于每个 UTF8 字符串。

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

C++ 中的 Utf-8:快速而肮脏的技巧 的相关文章

  • 了解 VerQueryValue

    在 MSDN 上 我注意到 VerQueryValue 函数的以下内容 lplp缓冲区 输出 低电压空洞当此方法返回时 包含指向 pBlock 指向的缓冲区中所请求版本信息的指针的地址 当关联的 pBlock 内存被释放时 lplpBuff
  • 在单个 C# 泛型方法中返回可为 null 和 null?

    C 泛型方法是否可以返回对象类型或 Nullable 类型 例如 如果我有一个安全的索引访问器List我想返回一个值 稍后我可以使用以下任一方法检查该值 null or HasValue 目前我有以下两种方法 static T SafeGe
  • C++:Linux平台上的线程同步场景

    我正在为 Linux 平台实现多线程 C 程序 其中我需要类似于 WaitForMultipleObjects 的功能 在搜索解决方案时 我发现有一些文章描述了如何在 Linux 中实现 WaitForMultipleObjects 功能
  • C++11 中具有 C 链接的复杂类型

    我需要将 C 库的标头包含到我的 C 11 代码中 现在 标头提供了涉及大量的例程和数据结构double complex到处都是 例如 include
  • MigraDoc 项目符号列表(漏洞)

    在我的解决方案中 我在 PDF 文件中使用项目符号列表 它看起来像这样 Solcellepaneler kr ver hverken autoriseret service eller tidskr vende vedligehold So
  • 如何通过实体键添加/删除与实体框架的多对多关系?

    I tried using Entities e new Entities EntityKey key new EntityKey Entities Users UserId 20 User user new User EntityKey
  • 如何让BackgroundWorker返回一个对象

    我需要做RunWorkerAsync 返回一个List
  • 为什么数组不可赋值? [复制]

    这个问题在这里已经有答案了 据我所知 C 标准禁止使用数组作为可修改的左值 即在赋值的左侧 int lhs 4 rhs 4 0 1 2 3 lhs rhs illegal 现在 我一直想知道为什么会这样 我可以看到上面的语句 以及写入数组的
  • 如何修复 TcpClient Ip 标头错误校验和

    我正在使用 System Net Sockets TcpClient 类 但每当我通过网络发送自定义数据包时 我都会在wireshark捕获上看到错误的校验和 我该如何修复它 问题是您在网络接口上设置了校验和卸载 这会导致您的网卡计算校验和
  • MouseDoubleClick 事件不会冒泡

    我的场景经过简化 我有一个包含员工行的 ListView 在每个员工行中 都有 增加 和 减少 按钮来调整他的工资 假设在我的程序中 双击 员工 行意味着 解雇此人 The problem是当我快速单击 增加 时 这会触发 ListView
  • C 风格强制转换与内在强制转换

    假设我已经定义了 m256d x我想提取低 128 位 我会做 m128d xlow mm256 castpd256 pd128 x 然而 我最近看到有人这样做 m128d xlow m128d x 是否有用于演员的首选方法 为什么要用第一
  • C++在子类中调用虚方法

    我有以下课程 class A protected A inner public virtual void doSomething 0 class B public A void doSomething if inner NULL inner
  • 关于 FirstOrDefault 或 SingleOrDefault

    FirstOrDefault 或 SingleOrDefault 将返回什么类型的数据 假设我的查询返回 3 条记录 例如 empid ename salary 1 joy 1500 2 rob 4500 3 jen 6500 所以如果我们
  • 使用 OpenSSL 库在 C++ 中生成 SHA 哈希值

    如何使用以下命令生成 SHA1 或 SHA2 哈希值OpenSSL https openssl org图书馆 我搜索了谷歌 找不到任何函数或示例代码 从命令行来看 很简单 printf compute sha1 openssl sha1 您
  • C# 的 user32 和内核方法列表 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有一个很好的清单来说明我们可以从中进口什么user32 dll and kernel dll并在 C 中使用 我是 Windows A
  • 为什么.net中的数组只实现IEnumerable而不实现IEnumerable

    我正在实现自己的 ArrayList 类 当我意识到这一点时 我感到很惊讶 public System Collections Generic IEnumerator
  • 在 Ubuntu 16.04 上编译 PCL 1.7,CMake 生成的 Makefile 中出现错误

    我正在尝试让 PCL 1 7 点云库 而不是其他 pcl 在 Ubuntu 16 04 上运行 我最终希望用于 C 的东西 但现在我只是想让这些例子工作 我使用的是 Ubuntu GNU 5 3 1 附带的默认编译器和 Cmake 版本 3
  • 初始化二维数组时出现分段错误

    我已经检查过我的代码是否正确地划分了内存空间 但是一旦我尝试将 2D 数组初始化为某些值 然后对这些值求和 我就会在 2x2 数组上收到分段错误 我想最终将我的代码扩展到更大的数组 但我什至无法让它在这里工作 我知道有很多关于 malloc
  • QT C++ QRegularExpression 多个匹配

    我想使用正则表达式从 QString html 中提取信息 我明确想使用正则表达式 无解析器解决方案 和类Q正则表达式 http qt project org doc qt 5 0 qtcore qregularexpression htm
  • Eclipse CDT C/C++:包含另一个项目的头文件

    我在 Eclipse CDT 中有两个 C 项目main and shared In shared我有一个名为calc h 我想在中使用这个标头main 所以我做了以下事情 added include calc h到相关文件main In

随机推荐

  • 运行 jQuery 函数 onclick

    所以我实现了一些 jQuery 它基本上通过由滑块激活的滑块来切换内容 a 标签 现在考虑一下 我宁愿让保存链接的 DIV 本身就是链接 我正在使用的 jQuery 在我的脑海中看起来像这样 a
  • 用 jQuery 收集表单中的所有项目

    如何收集 jQuery 中的所有复选框和下拉列表项进行保存 或者 对于最新版本的 jquery 您可以使用 http docs jquery com Ajax serialize http docs jquery com Ajax seri
  • 如何解决DEP6500和DEP6701错误?

    我有一个项目叫BTLE在它自己的解决方案中 加载项目并使用手机上的调试器运行它可以找到 我有第二个解决方案 可以很好地加载和编译 我添加了BTLE项目 添加 现有项目 到第二个解决方案 编译它并尝试在调试器中运行它 我可以看到应用程序已正确
  • 使用 PIG 从 Hive 表解析嵌套 XML 字符串

    我正在尝试使用 PIG 从 Hive 表中的字段而不是从 XML 文件中提取一些 XML 这是我读过的大多数示例的假设 XML 来自排列如下的表 ID XML string XML 字符串包含 n 行 始终包含最多 10 个属性中的至少一个
  • 如何在 Python 中写入原始二进制数据?

    我有一个 Python 程序 可以存储数据并将数据写入文件 数据是原始二进制数据 内部存储为str 我正在通过 utf 8 编解码器将其写出来 但是 我得到UnicodeDecodeError charmap codec can t dec
  • 使用 ASP.Net 2.0 创建 SOAP 请求

    我正在与服务器网站的技术联系人交谈 他希望我使用 Visual Studio 而我只想手写脚本 请参阅下文了解我需要生成的 SOAP 请求 我已将实际 URL 替换为虚拟 URL 正如您可能猜到的那样 我对 ASP 和 SOAP 还很陌生
  • Wagtail 文档:大文件(>2GB)上传失败

    我正在尝试使用 Wagtail 应用程序中内置的 wagtaildocs 应用程序上传文件 我已经使用 Nginx 的 Digital Ocean 教程方法设置了 Ubuntu 16 04 服务器 鳐鱼 Postgres 一些初步澄清 在我
  • 包签名与之前安装的版本不匹配

    这是我的项目 https github com kenpeter my hak news https github com kenpeter my hak news 它是直接复制https github com grigio HAgnost
  • Google Map API V3.0 - 如何检测 MapTypeId 更改

    要添加侦听器来检测缩放更改 请执行以下操作 google maps event addListener map zoom changed function 检测地图类型变化的代码是什么ROADMAP到另一个视图 例如SATELLITE 我可
  • .net/C# 中的网络

    有人可以为我指明学习如何在 C net 3 5 中进行网络连接的正确方向吗 欢迎提供代码示例和解释 基本上我正在寻找如何进行异步 多线程服务器 客户端模型 我对如何使用 WinSock 在 C 中实现这一点的基础知识相当满意 但尽管我所有的
  • 检测 osx 何时睡眠/从睡眠中恢复

    是否可以编写一个 python 程序 我认为我将作为守护进程运行 来检测 osx 何时进入睡眠状态以及何时从睡眠状态恢复 如果听起来我没有研究过这一点 我很抱歉 我已经超出了我的舒适区 不确定我是否需要从 python 委托给用 C 编写的
  • 如何在Python中以相同比例在同一图形上绘制两个3D矩阵图

    我有两个矩阵 我希望在同一个图上的两个子图上有相应的两个 3D 图 并且具有相同的 z 轴 到目前为止 这是我的代码 import numpy as np import matplotlib pyplot as plt from mpl t
  • 奇怪的海湾合作委员会行为

    给出以下 C 代码 struct vertex type float x y z vertex type vertex type float x float y float z x x y y z z typedef struct vert
  • 如何将包安装到 conda 创建的特定 virtualenv 中 [重复]

    这个问题在这里已经有答案了 我想在 conda 创建 virtualenv 后安装 python 包 但我收到以下错误 有谁知道如何将软件包安装到 conda 创建的 virtualenv 中 Users jzhang anaconda l
  • Java中的ConcurrentHashMap?

    有什么用ConcurrentHashMap在Java中 它有什么好处 它是如何工作的 示例代码也很有用 重点是提供一个实现HashMap那是线程安全的 多个线程可以读取和写入它 而不会接收到过期或损坏的数据 ConcurrentHashMa
  • 基于声明的安全性时的 http 客户端标头授权

    我正在从使用基于声明的安全性的 MVC 应用程序调用 REST api 我将如何设置身份验证标头 我没有密码 所以我想我不应该使用 Basic 如果使用 Bearer 如何获取令牌 Client DefaultRequestHeaders
  • 向 Magento 的订阅模块添加自定义字段

    Magento 中的新闻通讯订阅模块默认只有一个字段 电子邮件 在我向表单添加额外字段 例如国家 地区 后 如何让表单数据显示在 Magento 后端并作为电子邮件发送给预设收件人 谢谢 如果您想为 Magento 新闻通讯订阅者添加一些自
  • 使用 matplotlib 绘制类似 Python 极地时钟的图

    我正在尝试使用 Python 中的 matplotlib 以顺时针方式绘制数据 其风格为这个答案 https stackoverflow com questions 25898523 how to plot points on a cloc
  • 当 AutoGenerateColumns 为 nullable bool 时,WPF DataGrid 强制绑定 DataGridCheckBoxColumn

    我们有很多DataGrid具有动态数据绑定 所以我们总是使用AutoGenerateColumns True For bool列生成一个DataGridCheckBoxColumn但对于可为 null 的 bool bool 在 C 中 生
  • C++ 中的 Utf-8:快速而肮脏的技巧

    我知道有关于 utf 8 的各种问题 主要是关于操作 utf 8 字符串 之类对象的库 然而 我正在开发一个 国际化 项目 一个网站 我在其中编写了 c 后端 不要问 即使我们处理 utf 8 我们实际上也不需要这样的库 大多数时候 简单的