Question

Whats the most efficient way of removing a 'newline' from a std::string?

Was it helpful?

Solution

#include <algorithm>
#include <string>

std::string str;

str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());

The behavior of std::remove may not quite be what you'd expect. See an explanation of it here.

OTHER TIPS

If the newline is expected to be at the end of the string, then:

if (!s.empty() && s[s.length()-1] == '\n') {
    s.erase(s.length()-1);
}

If the string can contain many newlines anywhere in the string:

std::string::size_type i = 0;
while (i < s.length()) {
    i = s.find('\n', i);
    if (i == std::string:npos) {
        break;
    }
    s.erase(i);
}

You should use the erase-remove idiom, looking for '\n'. This will work for any standard sequence container; not just string.

Here is one for DOS or Unix new line:

    void chomp( string &s)
    {
            int pos;
            if((pos=s.find('\n')) != string::npos)
                    s.erase(pos);
    }
s.erase(std::remove(s.begin(), s.end(), '\n'), s.end());

The code removes all newlines from the string str.

O(N) implementation best served without comments on SO and with comments in production.

unsigned shift=0;
for (unsigned i=0; i<length(str); ++i){
    if (str[i] == '\n') {
        ++shift;
    }else{
        str[i-shift] = str[i];
    }
}
str.resize(str.length() - shift);

Another way to do it in the for loop

void rm_nl(string &s) {
    for (int p = s.find("\n"); p != (int) string::npos; p = s.find("\n"))
    s.erase(p,1);
}

Usage:

string data = "\naaa\nbbb\nccc\nddd\n";
rm_nl(data); 
cout << data; // data = aaabbbcccddd

Use std::algorithms. This question has some suitably reusable suggestions Remove spaces from std::string in C++

 std::string some_str = SOME_VAL;
 if ( some_str.size() > 0 && some_str[some_str.length()-1] == '\n' ) 
  some_str.resize( some_str.length()-1 );

or (removes several newlines at the end)

some_str.resize( some_str.find_last_not_of(L"\n")+1 );

If its anywhere in the string than you can't do better than O(n).

And the only way is to search for '\n' in the string and erase it.

for(int i=0;i<s.length();i++) if(s[i]=='\n') s.erase(s.begin()+i);

For more newlines than:

int n=0;
for(int i=0;i<s.length();i++){
    if(s[i]=='\n'){
        n++;//we increase the number of newlines we have found so far
    }else{
        s[i-n]=s[i];
    }
}
s.resize(s.length()-n);//to delete only once the last n elements witch are now newlines

It erases all the newlines once.

About answer 3 removing only the last \n off string code :

if (!s.empty() && s[s.length()-1] == '\n') {
    s.erase(s.length()-1);
}

Will the if condition not fail if the string is really empty ?

Is it not better to do :

if (!s.empty())
{
    if (s[s.length()-1] == '\n')
        s.erase(s.length()-1);
}

All these answers seem a bit heavy to me.

If you just flat out remove the '\n' and move everything else back a spot, you are liable to have some characters slammed together in a weird-looking way. So why not just do the simple (and most efficient) thing: Replace all '\n's with spaces?

for (int i = 0; i < str.length();i++) {
   if (str[i] == '\n') {
      str[i] = ' ';
   }
}

There may be ways to improve the speed of this at the edges, but it will be way quicker than moving whole chunks of the string around in memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top