std::string trim

本文介绍如何使用C++标准库函数实现字符串的前导和尾随空白字符的删除,包括ltrim、rtrim及trim函数的具体实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码来自

https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring?page=1&tab=votes#tab-top


std::string 没有trim函数,需要自己实现。

ltrim实现如下:

// trim from start (inplace)

staticinlinevoid ltrim(std::string &s) {

    s.erase(s.begin(), std::find_if(s.begin(),s.end(), [](int ch) {

        return !std::isspace(ch);

    }));

}

std::string的erase()函数有如下三种形式。http://www.cplusplus.com/reference/string/string/erase/

sequence (1)

 string& erase (size_t pos = 0, size_t len = npos);

character (2)

iterator erase (const_iterator p);

range (3)

iterator erase (const_iterator first, const_iterator last);

1 从pos开始删除len个字符

2 删除p指向的字符

3 删除半开区间[first,last)内的字符。(如果first和last一样,则不删除任何字符。)


ltrim使用的是第三种形式。

 

std::find_if函数原型。http://www.cplusplus.com/reference/algorithm/find_if/

 

template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

 

其中,第三个参数pred是一个函数,表示搜索的条件,符合条件即返回。如果没有符合条件的iterator,就会返回last。在实际使用中,last经常是end。而end不是最后一个元素,而是位于最后一个元素的后面。因此,不会出现明明没有符合条件的元素,却会把最后一个元素错误的当成符合条件的元素而返回的问题。

 

下面的例子演示了如何找到第一个奇数。

 

// find_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector
 
bool IsOdd (int i) {
  return ((i%2)==1);
}
 
int main () {
  std::vector<int> myvector;
 
  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);
 
  std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
  std::cout << "The first odd value is " << *it << '\n';
 
  return 0;
}

Output:

The first odd value is 25

 

如果上面程序中push_back的数字都是偶数的话,也不会把最后一个偶数错误地输出,而是会出现运行时错误。因为*it表示end中的内容,而end中没有任何内容。

 

[](int ch) { return !std::isspace(ch); }

这是一个lambda函数(匿名函数),相当于上面例子中的IsOdd。

在ltrim中的意思是不是空白的字符。

空白字符不只是空格,还包含下表中的字符。http://www.cplusplus.com/reference/cctype/isspace/

For the "C" locale, white-spacecharacters are any of:

' '

(0x20)

space (SPC)

'\t'

(0x09)

horizontal tab (TAB)

'\n'

(0x0a)

newline (LF)

'\v'

(0x0b)

vertical tab (VT)

'\f'

(0x0c)

feed (FF)

'\r'

(0x0d)

carriage return (CR)

 

其实,这里也可以把这个lambda函数写成有名字的函数,就像上面那个IsOdd。使用lambda只是更简洁一点而已。

 

关于lambda函数,这篇文章讲得非常清晰。

https://www.cnblogs.com/pzhfei/archive/2013/01/14/lambda_expression.html


ltrim的机制如下:

find_if会找到第一个不是空白的字符,erase会删除从第一个字符到找到的那个字符之前的所有字符。

如果string的第一个字符就不是空白字符,用半开区间表示就是[0,0),所以不会删除任何字符。

如果string全部是空白字符(比如说10个空格),找到的第一个不是空白的字符就是第11个字符,用半开区间表示就是[0,10),所以不会漏删最后一个空格。


全部的代码如下:

 

#include<algorithm>

#include<cctype>

#include<locale>

 

// trim from start (inplace)

staticinlinevoid ltrim(std::string &s) {

    s.erase(s.begin(), std::find_if(s.begin(),s.end(), [](int ch) {

        return !std::isspace(ch);

    }));

}

 

// trim from end (inplace)

staticinlinevoid rtrim(std::string &s) {

    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {

        return !std::isspace(ch);

    }).base(), s.end());

}

 

// trim from both ends (inplace)

staticinlinevoid trim(std::string &s) {

    ltrim(s);

    rtrim(s);

}

 

// trim from start(copying)

staticinline std::string ltrim_copy(std::string s) {

    ltrim(s);

    return s;

}

 

// trim from end (copying)

staticinline std::string rtrim_copy(std::string s) {

    rtrim(s);

    return s;

}

 

// trim from both ends(copying)

staticinline std::string trim_copy(std::string s) {

    trim(s);

    return s;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值