Skip to content

Instantly share code, notes, and snippets.

@rygorous
Created January 26, 2013 21:22
Show Gist options
  • Select an option

  • Save rygorous/4644703 to your computer and use it in GitHub Desktop.

Select an option

Save rygorous/4644703 to your computer and use it in GitHub Desktop.
This is not an acceptable way to strip whitespace from a string.
void RemoveWhitespace(cString &szString)
{
// Remove leading whitespace
size_t nFirstIndex = szString.find_first_not_of(_L(' '));
if(nFirstIndex != cString::npos)
{
szString = szString.substr(nFirstIndex);
}
// Remove trailing newlines
size_t nLastIndex = szString.find_last_not_of(_L('\n'));
while(nLastIndex != szString.length()-1)
{
szString.erase(nLastIndex+1,1);
nLastIndex = szString.find_last_not_of(_L('\n'));
};
// Tabs
nLastIndex = szString.find_last_not_of(_L('\t'));
while(nLastIndex != szString.length()-1)
{
szString.erase(nLastIndex+1,1);
nLastIndex = szString.find_last_not_of(_L('\t'));
};
// Spaces
nLastIndex = szString.find_last_not_of(_L(' '));
while(nLastIndex != szString.length()-1)
{
szString.erase(nLastIndex+1,1);
nLastIndex = szString.find_last_not_of(_L(' '));
};
}
@rygorous

Copy link
Copy Markdown
Author

For what it's worth, this code is used to read INI-like text files, and what I actually did to fix it was to stop copying strings around. My replacement function just takes a pair of iterators ("start" inclusive, "end" exclusive) and modifies it to strip whitespace:

static bool iswhite(int ch)
{
    return ch == _L(' ') || ch == _L('\t') || ch == _L('\n');
}

template<typename T>
static void RemoveWhitespace(T& start, T& end)
{
    while (start < end && iswhite(*start))
        ++start;

    while (end > start && iswhite(*(end - 1)))
        --end;
}

The code still eventually copies the extracted values into strings, but there's no reason to be creating tons of temporary strings in the meantime. For what it's worth, this is from a program that spent a significant amount of its (loading) time in RemoveWhitespace and its immediate callers, doing extremely inefficient text file parsing.

@dariomanesku

Copy link
Copy Markdown

It's probably not the topic, but C++ has a very elegant way of solving this problem. Here's how simple it is:

bool iswhite(int ch) 
{ 
    return ch == ' ' || ch == '\t' || ch == '\n';
}

void RemoveWhitespace(std::string &str)
{
    str.erase(std::remove_if(str.begin(), str.end(), iswhite), 
                  str.end());
}

@Poita

Poita commented Jan 27, 2013

Copy link
Copy Markdown

@dariomanesku: Your code removes all whitespace, not just leading and trailing.

@dariomanesku

Copy link
Copy Markdown

@Poita: Yes, that's exactly what it does, isn't that what's necessary? If not, I'm sorry, I haven't quite taken my time to look carefully at the code, I was just passing by. Also, then, the function name could be a little different.

@homeworkprod

Copy link
Copy Markdown

What about all the other whitespace characters? This targets only a rather small subset. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment