panthema / 2007 / 0530-StdString-Trim

C++ Code Snippet - In-Place and String-Copy Space Trimming of STL Strings

Posted on 2007-05-30 17:28 by Timo Bingmann at Permlink with 1 Comments. Tags: #c++ #code-snippet

Yesterday I once again stumbled upon whitespace trimming of STL strings: a check was required if the given user input is empty. Where "empty" also means some user-given string containing only spaces. After one hour of unproductive searching for something as simple as a space trimming function, I decided to put the resulting code here for future reference.

The following code snippet contains two versions of the function: in-place trimming and string-copy trimming. I prefer the copy-trimming function because they allow a more functional programming style. The functions only trim spaces, but can be modified by replacing each ' ' with something like " \n\r\t".

#include <string>

static inline void string_trim_left_inplace(std::string &str)
{
    str.erase(0, str.find_first_not_of(' '));
}

static inline void string_trim_right_inplace(std::string &str)
{
    str.erase(str.find_last_not_of(' ') + 1, std::string::npos);
}

static inline std::string string_trim_left(const std::string &str)
{
    std::string::size_type pos = str.find_first_not_of(' ');
    if (pos == std::string::npos) return std::string();

    return str.substr(pos, std::string::npos);
}

static inline std::string string_trim_right(const std::string &str)
{
    std::string::size_type pos = str.find_last_not_of(' ');
    if (pos == std::string::npos) return std::string();

    return str.substr(0, pos + 1);
}

static inline std::string string_trim(const std::string& str)
{
    std::string::size_type pos1 = str.find_first_not_of(' ');
    if (pos1 == std::string::npos) return std::string();

    std::string::size_type pos2 = str.find_last_not_of(' ');
    if (pos2 == std::string::npos) return std::string();

    return str.substr(pos1 == std::string::npos ? 0 : pos1,
                      pos2 == std::string::npos ? (str.length() - 1) : (pos2 - pos1 + 1));
}

static inline void string_trim_inplace(std::string& str)
{
    std::string::size_type pos = str.find_last_not_of(' ');
    if(pos != std::string::npos) {
        str.erase(pos + 1);
        pos = str.find_first_not_of(' ');
        if(pos != std::string::npos) str.erase(0, pos);
    }
    else
        str.erase(str.begin(), str.end());
}
#include <assert.h>

// Test the functions above
int main()
{
    // string-copy functions
    assert( string_trim_left("  abc  ") == "abc  " );
    assert( string_trim_left("abc  ") == "abc  " );
    assert( string_trim_left("  ") == "" );

    assert( string_trim_right("  abc  ") == "  abc" );
    assert( string_trim_right("  abc") == "  abc" );
    assert( string_trim_right("  ") == "" );

    assert( string_trim("  abc  ") == "abc" );
    assert( string_trim("abc  ") == "abc" );
    assert( string_trim("  abc") == "abc" );
    assert( string_trim("  ") == "" );

    // in-place functions
    std::string str1 = "  abc  ";
    std::string str2 = "abc  ";
    std::string str3 = "  ";

    string_trim_left_inplace(str1);
    string_trim_left_inplace(str2);
    string_trim_left_inplace(str3);

    assert( str1 == "abc  " );
    assert( str2 == "abc  " );
    assert( str3 == "" );

    str1 = "  abc  ";
    str2 = "  abc";
    str3 = "  ";

    string_trim_right_inplace(str1);
    string_trim_right_inplace(str2);
    string_trim_right_inplace(str3);

    assert( str1 == "  abc" );
    assert( str2 == "  abc" );
    assert( str3 == "" );

    str1 = "  abc  ";
    str2 = "  abc";
    str3 = "abc  ";
    std::string str4 = "  ";

    string_trim_inplace(str1);
    string_trim_inplace(str2);
    string_trim_inplace(str3);
    string_trim_inplace(str4);

    assert( str1 == "abc" );
    assert( str2 == "abc" );
    assert( str3 == "abc" );
    assert( str4 == "" );

    return 0;
}

Comment by CH WONG at 2009-11-04 02:21 UTC

Nice work..

Post Comment
Name:
E-Mail or Homepage:
 

URLs (http://...) are displayed, e-mails are hidden and used for Gravatar.

Many common HTML elements are allowed in the text, but no CSS style.