c++ - 如何正确跳过 unicode (UTF-8) 字符?
问题描述
我编写了一个解析器,结果证明它不能正确处理 UTF-8 文本。
解析器非常非常简单:
while(pos < end) {
// find some ASCII char
if (text.at(pos) == '@') {
// Check some conditions and if the syntax is wrong...
if (...)
createDiagnostic(pos);
}
pos++;
}
所以你可以看到我正在创建一个诊断pos
。但是,如果有一些 UTF-8 字符,则该 pos 是错误的(因为实际上 UTF-8 字符由多个char
.
我需要这个,因为诊断被发送到支持 UTF-8 的 VSCode。
我试图阅读一些关于 C++ 中 UTF-8 的文章,但我发现的每一个材料都是巨大的。我只需要跳过 UTF-8。
解决方案
如果代码点小于 128,则 UTF-8 将其编码为 ASCII(未设置最高位)。如果代码点等于或大于 128,则所有编码字节都将设置最高位。因此,这将起作用:
unsigned char b = <...>; // b is a byte from a utf-8 string
if (b&0x80) {
// ignore it, as b is part of a >=128 codepoint
} else {
// use b as an ASCII code
}
注意:如果要计算字符串中 UTF-8 代码点的数量,则必须计算字节数:
!(b&0x80)
:这意味着该字节是一个 ASCII 字符,或者(b&0xc0)==0xc0
:这意味着,该字节是多字节 UTF8 序列的第一个字节
推荐阅读
- angular - 带有查询参数的 url 重定向到 / 角度
- python - Z3 SMT 中的浮动操作
- aws-systems-manager - AWS 设置自动化任务以检查备份状态
- python - Keras - Conv1D 层 - 深度理解
- php - Laravel 使用两个 php.ini 文件
- scala - Spark:从异构数据中写入 Paquet
- r - 生成行组合,然后将函数应用于每一行的值
- c# - C# 访问传递给窗口的 ref 变量,从另一个窗口函数
- flutter - 如何在 GridView 中调整没有声明高度/宽度的容器的大小?
- apache-spark - Mesos master 在框架拆解期间崩溃