Wednesday, March 24, 2010

Trim leading or trailing white spaces off a string in C++


Unlike Java, there is no built-in function to remove leading or trailing white spaces from a string in C++.

We can write a function to implement this.

  1 void trim(string& s)
  2 {
  3    size_t p = s.find_first_not_of(" \t");
  4    s.erase(0, p);
  5 
  6    p = s.find_last_not_of(" \t");
  7    if (string::npos != p)
  8       s.erase(p+1);
  9 }

Line 1: "s" is a reference parameter through which the original string is passed in and the result will be passed out.

Line 3: the string's built-in function find_first_not_of() returns the position of the first character which is not in the list of white spaces (' ' or '\t'). Since we are searching from the first character -- position 0, the result is also the number of leading white spaces.

Line 4: erase "p" characters from the beginning of the string, i.e. the leading white spaces. If there is no non-white-space character, line 3 will return string::npos. s.erase(0, string::npos) will then erase the whole string.

Line 6: the string's built-in function find_last_not_of() returns the position of the last character which is not a white space.

Line 7: if there is not trailing white spaces, line 6 returns string::npos. Therefore, our job is done.

Line 8: Otherwise, erase the trailing white spaces which starts from the next character to "p".

To test it, run this:

#include <string>
#include <iostream>

using namespace std;

void trim(string& s)
{
   size_t p = s.find_first_not_of(" \t");
   s.erase(0, p);

   p = s.find_last_not_of(" \t");
   if (string::npos != p)
      s.erase(p+1);
}

int main()
{
   string a = "   a   ";
   string b = "";
   string c = "       ";
   string d = "   \t  ";

   trim(a);
   trim(b);
   trim(c);
   trim(d);

   cout << ":" << a
        << ":" << b
        << ":" << c
        << ":" << d
        << ":" << endl;
   
   return 0;
}

1 comment:

daggoogle said...

Now C++11 is here, there are more compact ways to do this with lambdas. Assuming you want to strip both end of the string:

static inline string &ltrim(string &s)
{
s.erase(s.begin(),find_if_not(s.begin(),s.end(),[](int c){return isspace(c);}));
return s;
}

static inline string &rtrim(string &s)
{ s.erase(find_if_not(s.rbegin(),s.rend(),[](int c){return isspace(c);}).base(), s.end());
return s;
}

static inline string trim(const string &s)
{
string t=s;
return ltrim(rtrim(t));
}

Note ltrim() and rtrim() return references. They are destructive.

 
Get This <