Trim whitespace from a String

128,673

Solution 1

Your code is fine. What you are seeing is a linker issue.

If you put your code in a single file like this:

#include <iostream>
#include <string>

using namespace std;

string trim(const string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (string::npos == first)
    {
        return str;
    }
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last - first + 1));
}

int main() {
    string s = "abc ";
    cout << trim(s);

}

then do g++ test.cc and run a.out, you will see it works.

You should check if the file that contains the trim function is included in the link stage of your compilation process.

Solution 2

Here is how you can do it:

std::string & trim(std::string & str)
{
   return ltrim(rtrim(str));
}

And the supportive functions are implemeted as:

std::string & ltrim(std::string & str)
{
  auto it2 =  std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( str.begin() , it2);
  return str;   
}

std::string & rtrim(std::string & str)
{
  auto it1 =  std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( it1.base() , str.end() );
  return str;   
}

And once you've all these in place, you can write this as well:

std::string trim_copy(std::string const & str)
{
   auto s = str;
   return ltrim(rtrim(s));
}

Try this

Solution 3

I think that substr() throws an exception if str only contains the whitespace.

I would modify it to the following code:

string trim(string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (first == std::string::npos)
        return "";
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last-first+1));
}

Solution 4

Using a regex

#include <regex>
#include <string>

string trim(string s) {
    regex e("^\\s+|\\s+$");   // remove leading and trailing spaces
    return regex_replace(s, e, "");
}

// if you prefer the namespaced version
std::string trim(std::string s) {
    std::regex e("^\\s+|\\s+$"); // remove leading and trailing spaces
    return std::regex_replace(s, e, "");
}

Credit to: https://www.regular-expressions.info/examples.html for the regex

Share:
128,673
follmer
Author by

follmer

Updated on August 17, 2022

Comments

  • follmer
    follmer almost 2 years

    I know there are several ways to do this in Java and C that are nice, but in C++ I can't seem to find a way to easily implement a string trimming function.

    This is what I currently have:

    string trim(string& str)
    {
        size_t first = str.find_first_not_of(' ');
        size_t last = str.find_last_not_of(' ');
        return str.substr(first, (last-first+1));
    }
    

    but whenever I try and call

    trim(myString);
    

    I get the compiler error

    /tmp/ccZZKSEq.o: In function `song::Read(std::basic_ifstream<char, 
    std::char_traits<char> >&, std::basic_ifstream<char, std::char_traits<char> >&, char const*, char const*)':
    song.cpp:(.text+0x31c): undefined reference to `song::trim(std::string&)'
    collect2: error: ld returned 1 exit status
    

    I am trying to find a simple and standard way of trimming leading and trailing whitespace from a string without it taking up 100 lines of code, and I tried using regex, but could not get that to work as well.

    I also cannot use Boost.