Saturday, July 11, 2009

C++ Whitespace Trimming Functions

Some simple functions for removing leading or trailing whitespace from strings in C++. It uses isspace() and your current locale (by default) to determine what is considered whitespace (e.g., space, tab, newline, etc.) and modifies the strings in-place.

The header file, btrim.hpp:

#ifndef BTRIM_HPP
#define BTRIM_HPP

#include <string>
#include <locale>

/**
* Strip leading whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void ltrim(std::string& str, const std::locale& loc = std::locale());

/**
* Strip trailing whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void rtrim(std::string& str, const std::locale& loc = std::locale());

/**
* Strip both leading and trailing whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void btrim(std::string& str, const std::locale& loc = std::locale());

#endif // BTRIM_HPP

The implementation file, btrim.cpp:

#include "btrim.hpp"

using namespace std;

void ltrim(string& str, const locale& loc) {
string::size_type pos = 0;
while (pos < str.size() && isspace(str[pos], loc)) pos++;
str.erase(0, pos);
}

void rtrim(string& str, const locale& loc) {
string::size_type pos = str.size();
while (pos > 0 && isspace(str[pos - 1], loc)) pos--;
str.erase(pos);
}

void btrim(string& str, const locale& loc) {
ltrim(str, loc);
rtrim(str, loc);
}

Example usage:

// Example use of trim whitespace functions
#include <string>
#include <iostream>
#include "btrim.hpp"

using namespace std;

int main () {
string s = " zort ";
btrim(s); /* trim spaces, both leading and trailing */
cout << "Trimmed string: |" << s << "|" << endl;
}

3 comments:

Brian said...

I realize this is an old post, but it inspired me on my own implementation I've been working on. I've never heard of isspace before, it's something I have to look up. But from doing some benchmarking I found your implementation can be sped up by changing it to ' ' == and changing pos-- to --pos (though I guess maybe I'd prefer to pass in the character for the local instead of just using ' ').

You figured out how to loop through the string properly even though one might have to worry about the unsigned int (size_type) when subtracting the position, but you got around this. Instead of solving this problem, I actually worked around it and found a different implementation that I think works fairly well; you don't have to check using str[pos - 1], just str[pos]. You can find these thoughts summed up here: http://leetnightshade.com/archives/328

I've just been doing some research on the topic, and would like to thank you for a good post.

Unknown said...

Thank you so much. I have been working on a project for the last 6 hours trying to do exactly this. I'm relatively new to C++ and your class btrim works perfectly.

Mudassir Saeed said...

Thanks