A trim implementation for std::string

Introduction

The C++ Standard Template Library (STL, for short) provides the handy std::string class, which provides a lot of common string facilities. However, the well-known trim operation was not implemented. The trimoperation consists of removing all unused spaces placed before and after the characters into a string. For example, let's say you have a textbox in a program where the user should type their name. Then, the user types the following:

"  Rodrigo Dias "

It would be interesting if you could remove the spaces before and after the name if, for example, you are about to include this string in a database. In this article, we will discuss three easy implementations of  trim , both applied to the  std::string  class.


First implementation

In this first implementation, the idea is to extract the substring within the string, so we have just what interests. The code is shown below:

void trim1(string& str)
{
  string::size_type pos1 = str.find_first_not_of(' ');
  string::size_type pos2 = str.find_last_not_of(' ');
  str = str.substr(pos1 == string::npos ? 0 : pos1, 
    pos2 == string::npos ? str.length() - 1 : pos2 - pos1 + 1);
}


Second implementation, faster

The second implementation is faster, as you can see yourself if you perform some benchmarks as I did. The idea here is to search the string for the last character before the last space characters. If none is found, then the string is composed only of spaces, so it's completely erased. Else we remove the spaces at the end of the string, based on the found index.

Next step, we search for the first character different from space. Then we remove everything before it. The code of this implementation is shown below:

void trim2(string& str)
{
  string::size_type pos = str.find_last_not_of(' ');
  if(pos != string::npos) {
    str.erase(pos + 1);
    pos = str.find_first_not_of(' ');
    if(pos != string::npos) str.erase(0, pos);
  }
  else str.erase(str.begin(), str.end());
}
This implementation is faster because we have two calls to erase, instead of a string copy (more expensive).


Third implementation, C++11

This implementation is possibly the most elegant, and it uses C++11 lambdas (also, I'm writing this 9 years later, so my programming skills are slightly better). Here, we strip space characters from the beginning and from the end using the erase method, which works upon iterators. The two erase calls are in fact a left-trim and a right-trim. The catch is that we directly pass iterators returned from the find_if function, which runs through the string searching for the bounds. The isspace function is responsible to decide what is a space character.

#include <algorithm>
#include <cctype>
#include <string>

string& trim3(string& str)
{
  str.erase(str.begin(), find_if(str.begin(), str.end(),
    [](char& ch)->bool { return !isspace(ch); }));
  str.erase(find_if(str.rbegin(), str.rend(),
    [](char& ch)->bool { return !isspace(ch); }).base(), str.end());
  return str;
}  

On the second erase call, we need to call the base method because we're using reverse iterators to search from the end of the string; base returns a copy of the same iterator that can go forward. Also, as a bonus, ourtrim3 returns a reference to the same passed string object.

Conclusion

The trim method may be very useful sometimes, and we discussed an implementation of a good one if we are working with the std::string class. Below is the simplest example of how to use it, dealing with the previously given input:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值