C++ 字符串去除空格

用户在输入框里填写账号名或搜索词时,经常会在文字前后不小心多敲几个空格。如果不先清理掉这些多余的空格,后续在比对或查询数据时就容易出错。

在 C++ 中,std::string 没有提供现成的 trim() 函数。平时清理空格一般分为 2 种情况:一种是只去掉首尾两端的空格,保留句子中间的正常空格;另一种是把字符串里的所有空格全部删掉。

去除开头或末尾的空格

std::string 提供了 find_first_not_of() 和 find_last_not_of() 两个查找函数。我们只需要先找出非空格字符的边界下标,再配合 substr() 函数截取出来,就能去掉开头或末尾的空格。

语法:

std::size_t first = str.find_first_not_of(' ');
std::size_t last = str.find_last_not_of(' ');

说明:

从英文意思上很容易记住:first_not_of 表示 “第一个不是……的字符”,last_not_of 表示 “最后一个不是……的字符”。这两个函数的具体作用如下:

  • find_first_not_of(' '):从左往右查找 “第一个不是空格” 的字符,返回它的下标位置。
  • find_last_not_of(' '):从右往左查找 “最后一个不是空格” 的字符,返回它的下标位置。

如果整个字符串里全都是空格,或者本来就是空字符串,找不到任何非空格字符,它们都会跟 find() 函数一样返回 std::string::npos。

示例 1:去除开头的空格

#include <iostream>
#include <string>

int main() {
    std::string text = "   Hello C++";
    std::size_t first = text.find_first_not_of(' ');

    if (first == std::string::npos) {
        text = "";
    } else {
        text = text.substr(first);
    }

    std::cout << "[" << text << "]" << '\n';
    return 0;
}

运行结果如下。

[Hello C++]

分析:

上面代码中,text.find_first_not_of(' ') 从左往右跳过开头的 3 个空格,找到第一个非空格字符 'H' 的下标 3。接着调用 text.substr(first) 从下标 3 截取到末尾,就把开头的空格去掉了。

如果原字符串里全都是空格,查找结果就会等于 std::string::npos,此时 if 分支会直接把 text 设为空字符串 "",避免残留空格。

同理,如果想要去除字符串末尾的空格,只需要使用 find_last_not_of(' ') 找到最后一个非空格字符的位置即可。下面我们来看一个例子。

示例 2:去除末尾的空格

#include <iostream>
#include <string>

int main() {
    std::string text = "Hello C++   ";
    std::size_t last = text.find_last_not_of(' ');

    if (last == std::string::npos) {
        text = "";
    } else {
        text = text.substr(0, last + 1);
    }

    std::cout << "[" << text << "]" << '\n';
    return 0;
}

运行结果如下。

[Hello C++]

分析:

在这个例子中,text.find_last_not_of(' ') 从右往左跳过末尾的 3 个空格,找到最后一个非空格字符 '+' 的下标 last,其值为 8。

可能有些小伙伴会问:为什么截取时要写成 text.substr(0, last + 1),要在 last 后面加 1 呢?因为下标是从 0 开始计算的,从下标 0 到下标 8 一共有 8 + 1(共 9)个字符,而 substr() 的第 2 个参数要求的正是字符个数。

同时去除首尾两端的空格

在实际开发中,更常见的需求是同时去掉字符串开头和末尾的空格,只保留中间的有效内容,比如把 " Hello lvyenet " 清理成 "Hello lvyenet"。

我们可以把上面两个查找函数结合起来:先找出第一个非空格字符的下标 first,再找出最后一个非空格字符的下标 last。

由于首尾这两个非空格字符本身都要保留,就像看书时从第 3 页读到第 6 页一共读了 6 - 3 + 1 = 4 页一样,两个下标相减之后还要加 1,算出来的 last - first + 1 才是中间有效内容的字符个数。

示例 3:去除首尾两端的空格

#include <iostream>
#include <string>

int main() {
    std::string text = "  Hello lvyenet  ";
    std::size_t first = text.find_first_not_of(' ');

    if (first == std::string::npos) {
        text = "";    // 全是空格时设为空串
    } else {
        std::size_t last = text.find_last_not_of(' ');
        text = text.substr(first, last - first + 1);
    }

    std::cout << "[" << text << "]" << '\n';
    return 0;
}

运行结果如下。

[Hello lvyenet]

分析:

在 " Hello lvyenet " 中,首字母 'H' 的下标 first 为 2,尾字母 't' 的下标 last 为 14,算出有效长度 last - first + 1 为 13。

接着调用 text.substr(2, 13),首尾两端的空格就被干净去掉了,而两个单词中间的正常空格依然保留了下来。

提示 如果字符串首尾还可能包含 \t、\n、\r 等转义字符,可以把查找参数换成字符串 " \t\n\r",一次性把首尾的各种空白字符全部清理干净。

C++20 删除所有空格

前面的做法只清理首尾两端,保留了字符串内部的空格。如果我们的需求是把字符串首尾和中间出现的所有空格全部删掉,从 C++20 标准开始,<string> 头文件直接提供了 std::erase() 函数,一行代码就能删除字符串中所有指定的字符。

语法:

std::erase(str, ' ');

说明:

调用 std::erase(str, ' ') 会直接在原字符串 str 上把所有的空格字符 ' ' 全部删除,字符串的长度也会随之缩短。

示例 4:删除所有空格

#include <iostream>
#include <string>

int main() {
    std::string text = " 2026 - 10 - 23 ";
    std::erase(text, ' ');

    std::cout << "[" << text << "]" << '\n';
    return 0;
}

运行结果如下。

[2026-10-23]

分析:

" 2026 - 10 - 23 " 不仅首尾有空格,连字符 "-" 的左右两侧也都有空格。执行 std::erase(text, ' '); 后,字符串里所有的空格都被直接删除,变成了紧凑的 "2026-10-23"。

常见问题

1. text.erase() 和 std::erase() 名字都叫 erase,它们有什么区别?

这两个函数的名字虽然相同,但调用方式和删除规则不一样,小伙伴们不要搞混了:

text.erase(pos, count):属于 std::string 的成员函数,按 “下标位置和字符个数” 删除。比如 text.erase(0, 3) 表示从下标 0 开始连续删除 3 个字符。

std::erase(text, ' '):属于 C++20 新增的标准库函数,按 “字符内容” 删除,会把 text 里所有的 ' ' 全部删掉。同理,如果第 2 个参数传入 '-',就会删掉字符串里所有的连字符。

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号