C++ Remove new line from multiline string

C++StringMultiline

C++ Problem Overview


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

C++ Solutions


Solution 1 - C++

#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.

Solution 2 - C++

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);
}

Solution 3 - C++

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

Solution 4 - C++

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);
    }

    

Solution 5 - C++

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

Solution 6 - C++

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

Solution 7 - C++

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);

Solution 8 - 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 );

Solution 9 - C++

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

Solution 10 - C++

Slight modification on edW's solution to remove all exisiting endline chars

void chomp(string &s){
size_t pos;
while (((pos=s.find('\n')) != string::npos))
    s.erase(pos,1);
}

Note that size_t is typed for pos, it is because npos is defined differently for different types, for example, -1 (unsigned int) and -1 (unsigned float) are not the same, due to the fact the max size of each type are different. Therefore, comparing int to size_t might return false even if their values are both -1.

Solution 11 - C++

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.

Solution 12 - C++

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);
}

Solution 13 - C++

To extend @Greg Hewgill's answer for C++11:

If you just need to delete a newline at the very end of the string:

This in C++98:

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

...can now be done like this in C++11:

if (!s.empty() && s.back() == '\n') {
    s.pop_back();
}

Optionally, wrap it up in a function. Note that I pass it by ptr here simply so that when you take its address as you pass it to the function, it reminds you that the string will be modified in place inside the function.

void remove_trailing_newline(std::string* str) 
{
    if (str->empty())
    {
        return;
    }

    if (str->back() == '\n') 
    {
        str->pop_back();
    }
}

// usage
std::string str = "some string\n";
remove_trailing_newline(&str);

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

As far as the most efficient way goes--that I'd have to speed test/profile and see. I'll see if I can get back to you on that and run some speed tests between the top two answers here, and a C-style way like I did here: Removing elements from array in C. I'll use my nanos() timestamp function for speed testing.

Other References:

  1. See these "new" C++11 functions in this reference wiki here: https://en.cppreference.com/w/cpp/string/basic_string
  2. https://en.cppreference.com/w/cpp/string/basic_string/empty
  3. https://en.cppreference.com/w/cpp/string/basic_string/back
  4. https://en.cppreference.com/w/cpp/string/basic_string/pop_back

Solution 14 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionshergillView Question on Stackoverflow
Solution 1 - C++lukeView Answer on Stackoverflow
Solution 2 - C++Greg HewgillView Answer on Stackoverflow
Solution 3 - C++copproView Answer on Stackoverflow
Solution 4 - C++edWView Answer on Stackoverflow
Solution 5 - C++user172783View Answer on Stackoverflow
Solution 6 - C++hrntView Answer on Stackoverflow
Solution 7 - C++P ShvedView Answer on Stackoverflow
Solution 8 - C++Kirill V. LyadvinskyView Answer on Stackoverflow
Solution 9 - C++mkunglaView Answer on Stackoverflow
Solution 10 - C++BelowAleView Answer on Stackoverflow
Solution 11 - C++csizView Answer on Stackoverflow
Solution 12 - C++Christophe Van ReuselView Answer on Stackoverflow
Solution 13 - C++Gabriel StaplesView Answer on Stackoverflow
Solution 14 - C++T.E.D.View Answer on Stackoverflow