全角字符的判断依据是Unicode码点是否落在U+FF01–U+FF60、U+FFE0–U+FFE6、U+4E00–U+9FFF等典型区间,需先将UTF-8字符串解码为码点再逐个判断。

全角字符的判断依据是什么
全角字符在 Unicode 中没有统一编码范围,但中文、日文、韩文等常用全角符号集中在 U+FF01–U+FF60(全角 ASCII 对应区)、U+FFE0–U+FFE6(全角标点)以及 CJK 统一汉字区(如 U+4E00–U+9FFF)。注意:不能只看字节长度(比如 UTF-8 下中文是 3 字节),因为单个 char 无法表示 Unicode 码点;C++ 中需先将字符串解码为 Unicode 码点再判断。
用 std::wstring_convert + std::codecvt_utf8_utf16 解码 UTF-8 字符串
这是 C++11 提供的(虽已弃用但仍是目前最易上手的跨平台方案)。关键点:必须逐个提取 UTF-8 字符对应的 Unicode 码点,再检查是否落在全角区间内。常见错误是直接对 std::string 的 operator[] 遍历——这会把多字节 UTF-8 拆成无效字节,导致误判。
实操建议:
- 用
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>将std::string转为std::u16string - 遍历
std::u16string中每个char16_t:UTF-16 中 BMP 字符直接对应码点;遇到代理对(surrogate pair)需合并计算(但常见中文基本都在 BMP 内) - 判断逻辑示例:
if (cp >= 0xFF01 && cp = 0x4E00 && cp
更现代的替代方案:C++20 std::text_encoding 或第三方库
C++20 引入了 std::text_encoding(尚未广泛实现),当前主流方案是用 ICU 或 utf8cpp。若项目已用 utf8cpp,可直接用 utf8::next() 提取码点:
立即学习“C++免费学习笔记(深入)”;
unsigned long cp;
auto it = str.begin();
while (it != str.end()) {
it = utf8::next(it, str.end(), cp);
if ((cp >= 0xFF01 && cp <= 0xFF60) ||
(cp >= 0x4E00 && cp <= 0x9FFF) ||
(cp >= 0x3000 && cp <= 0x303F)) { /* 全角标点 */ }
}注意:utf8::next() 返回的是 unsigned long,能覆盖全部 Unicode 码点;而 char16_t 最大仅支持到 0xFFFF,处理补充平面字符(如 emoji)时会出错。
容易忽略的边界情况
全角判断不是非黑即白:有些字符(如全角空格 U+3000)属于全角但不在汉字区间;半宽片假名/平假名(U+3040–U+309F, U+30A0–U+30FF)也属全角范畴;而部分符号(如全角括号、顿号)在 U+3000–U+303F 区间。漏掉这些会导致误判。
另外,Windows 控制台默认使用 GBK 编码,若输入的是 GBK 编码字符串,必须先转 UTF-8 再解码——否则 std::wstring_convert 会解析失败或产生乱码码点。
真正要判断“是否为全角”,本质是判断“该字符是否属于东亚文字全角排版所用的 Unicode 区块”,而不是看它显示宽度或字节数。这个逻辑一旦写死区间,就很难覆盖所有语言场景,尤其涉及古籍或扩展汉字时。


















