c++oding="utf-8" ?>
全角空格的 unicode 编码是 0x3000(u+3000),在 utf-8 中占 3 字节(\xe3\x80\x80),不同于 ascii 空格(0x20);直接用 std::erase 或 ' ' 匹配无效,需通过 utf-8 解码、wstring 处理或硬编码字节序列安全删除。

全角空格的 Unicode 编码是 0x3000,不是 ' '
很多人一上来就用 std::erase 或循环删 ' ',结果发现没用——因为全角空格(中文输入法下按空格键产生的)是 Unicode 字符 U+3000,对应宽字符 L' '(注意这个字符比 ASCII 空格宽),在 std::string 中占 3 字节(UTF-8 编码下),在 std::wstring 中占 2 字节(Windows 下通常为 UTF-16)。直接匹配 ' ' 或 " " 完全无效。
判断是否为全角空格,最稳妥的方式是检查 UTF-8 字节序列或转换为 Unicode 码点。但实际项目中,多数场景可简化处理:
- 若字符串确定为 UTF-8 编码(如 Linux/macOS 下常见),全角空格编码为
"\xE3\x80\x80" - 若使用
std::wstring(如 Windows GUI 程序),全角空格就是L' '(注意:这不是普通空格,复制时容易混淆) - 混用半角/全角空格时,建议统一用 Unicode 码点判断,而非字节匹配
用 std::erase_if 删除 UTF-8 中的全角空格(C++20)
适用于 std::string 存储 UTF-8 字符串的场景(如大多数跨平台 CLI 工具)。不能直接用 char 比较,必须识别多字节序列。最简方案是硬编码匹配 "\xE3\x80\x80":
std::string s = "hello world"; // 注意中间是全角空格 s.erase(std::remove(s.begin(), s.end(), '\xE3'), s.end()); // ❌ 错!会删掉所有 \xE3 字节
正确做法是遍历 UTF-8 字节流,或用第三方库(如 ICU、utf8cpp)。但若只处理全角空格且不引入依赖,可用以下安全扫描:
- 从后往前遍历,每次检查当前位置是否为
"\xE3\x80\x80"的起始字节(\xE3)且后续两字节匹配 - 更推荐:先转成
std::wstring(用std::mbstowcs或平台 API),再删L' ',最后转回 - C++20 起,
std::erase_if可配合自定义谓词,但需确保谓词能正确解析 UTF-8
Windows 下用 std::wstring 直接删 L' '
Windows 控制台和 WinAPI 多数默认宽字符,std::wstring 是更自然的选择。全角空格在 wchar_t 中就是一个独立字符:
std::wstring ws = L"test test"; // L' ' 是单个 wchar_t
std::erase_if(ws, [](wchar_t c) { return c == L' '; }); // ✅ 正确
注意:L' ' 必须从可靠来源复制(比如直接写宽字符串字面量),不要手动输入——IDE 输入法可能自动转成半角,或粘贴时丢失。验证方法:打印 (int)ws[4] 应得 12288(即 0x3000)。
- VS 编译器默认源文件编码为 GBK 时,
L" "可能无法正确解析,建议将源文件保存为 UTF-8 with BOM - 若读取文件得到
std::string,需先用MultiByteToWideChar(CP_UTF8, ...)转换,不能直接用std::mbstowcs(它依赖 locale) -
std::erase_if在 C++20 前不可用,可用ws.erase(std::remove(ws.begin(), ws.end(), L' '), ws.end())
正则方式要小心 \s 不匹配全角空格
std::regex 的 \s 默认只匹配 ASCII 空白(' '、'\t'、'\n' 等),完全不识别 U+3000。即使 locale 设为 "zh_CN.UTF-8",标准库 regex 实现(libstdc++ / libc++)也基本不支持 Unicode 类别匹配。
- 写
std::regex re(L" ");(宽正则)仅在std::wregex+std::wstring下有效,且需确保编译器支持宽字符正则(MSVC 支持较好,GCC 有 bug) - 更稳妥:不用正则,改用
std::find扫描L" "或"\xE3\x80\x80"子串,再用std::string::erase删除 - 如果必须用正则且支持 ICU,可用
icu::RegexPattern,但代价是链接额外库
真正麻烦的从来不是“怎么删”,而是“怎么确认删对了”——尤其当字符串来自用户输入、剪贴板或网页抓取时,可能混入 U+2000~U+200B 等各种空白符,全角空格只是其中最常见的一种。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











