views:

725

answers:

4

How to remove spaces from a string object in C++.
For example, how to remove leading and trailing spaces from the below string object.

//Original string: "         This is a sample string                    "
//Desired string: "This is a sample string"

The string class, as far as I know, doesn't provide any methods to remove leading and trailing spaces.

To add to the problem, how to extend this formatting to process extra spaces between words of the string. For example,

// Original string: "          This       is         a sample   string    " 
// Desired string:  "This is a sample string"

Using the string methods mentioned in the solution, I can think of doing these operations in two steps.

  1. Remove leading and trailing spaces.
  2. Use find_first_of, find_last_of, find_first_not_of, find_last_not_of and substr, repeatedly at word boundaries to get desired formatting.
+6  A: 

Boost string trim algorithm

jon hanson
+12  A: 

It's called trimming. You want to use find_first_not_of to get the index of the first non-whitespace character, then find_last_not_of to get the index from the end that isn't whitespace. With these, use substr to get the sub-string with no surrounding whitespace.

In response to your edit, I don't know the term but I'd guess something along the lines of "reduce", so that's what I called it. :) (Note, I've changed the white-space to be a parameter, for flexibility)

#include <iostream>
#include <string>

const std::string trim(const std::string& pString,
                       const std::string& pWhitespace = " \t")
{
    const size_t beginStr = pString.find_first_not_of(pWhitespace);
    if (beginStr == std::string::npos)
    {
        // no content
        return "";
    }

    const size_t endStr = pString.find_last_not_of(pWhitespace);
    const size_t range = endStr - beginStr + 1;

    return pString.substr(beginStr, range);
}

const std::string reduce(const std::string& pString,
                         const std::string& pFill = " ",
                         const std::string& pWhitespace = " \t")
{
    // trim first
    std::string result(trim(pString, pWhitespace));

    // replace sub ranges
    size_t beginSpace = result.find_first_of(pWhitespace);
    while (beginSpace != std::string::npos)
    {
        const size_t endSpace =
                        result.find_first_not_of(pWhitespace, beginSpace);
        const size_t range = endSpace - beginSpace;

        result.replace(beginSpace, range, pFill);

        const size_t newStart = beginSpace + pFill.length();
        beginSpace = result.find_first_of(pWhitespace, newStart);
    }

    return result;
}

int main(void)
{
    const std::string bleh = "    too much\t   \tspace\t\t\t  ";

    std::cout << "[" << trim(bleh) << "]" << std::endl;
    std::cout << "[" << reduce(bleh) << "]" << std::endl;
    std::cout << "[" << reduce(bleh, "-") << "]" << std::endl;
}

Though if you can boost, I'd recommend it.

GMan
i assume you meant 'size_t'. and you've got an off-by-one on the substring, should be substr(beginStr, endStr - beginStr + 1);
goldPseudo
Should `site_t` be `size_t`? And I think where you have the comment `no whitespace` means the string is all whitespace or empty.
Fred Larson
Thanks, fixed the `size_t` typo and off-by-one in the edit, but didn't notice my comment was inverted, thanks.
GMan
Ok, I think you got it now.
Fred Larson
@GMan very elegant solution. Thanks.
Ankur
A: 
    char *str = (char*) malloc(50 * sizeof(char));
    strcpy(str, "    some random string (<50 chars)  ");

    while(*str == ' ' || *str == '\t' || *str == '\n')
            str++;

    int len = strlen(str);

    while(len >= 0 && 
            (str[len - 1] == ' ' || str[len - 1] == '\t' || *str == '\n')
    {
            *(str + len - 1) = '\0';
            len--;
    }

    printf(":%s:\n", str);
Amarghosh
A: 

What about

http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove?

std::string s("...");

s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );

Sorry. I saw too late that you don't want to remove all whitespace.

vt