std::string trim

xiaoxiao2021-02-28  53

代码来自

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;

}

转载请注明原文地址: https://www.6miu.com/read-2630936.html

最新回复(0)