C++ Eliminar nueva línea de la cadena multilínea


¿Cuál es la forma más eficiente de eliminar una 'nueva línea' de una cadena std::?

Author: shergill, 2009-09-28

12 answers

#include <algorithm>
#include <string>

std::string str;

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

El comportamiento de std::remove puede no ser lo que esperarías. Ver una explicación de ello aquí.

 92
Author: luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:09:42

Si se espera que la nueva línea esté al final de la cadena, entonces:

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

Si la cadena puede contener muchas líneas nuevas en cualquier lugar de la cadena:

std::string::size_type i = 0;
while (i < s.length()) {
    i = s.find('\n', i);
    if (i == std::string:npos) {
        break;
    }
    s.erase(i);
}
 7
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:06:24

Debes usar el modismo erase-remove, buscando '\n'. Esto funcionará para cualquier contenedor de secuencia estándar; no solo string.

 7
Author: coppro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:00:10

Aquí hay una para DOS o Unix nueva línea:

    void chomp( string &s)
    {
            int pos;
            if((pos=s.find('\n')) != string::npos)
                    s.erase(pos);
    }
 4
Author: edW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-09 17:42:38
s.erase(std::remove(s.begin(), s.end(), '\n'), s.end());
 1
Author: hrnt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:08:31

El código elimina todas las nuevas líneas de la cadena str.

O(N) implementación mejor servida sin comentarios sobre SO y con comentarios en producción.

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);
 1
Author: P Shved,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:09:26

Otra forma de hacerlo en el bucle for

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

Uso:

string data = "\naaa\nbbb\nccc\nddd\n";
rm_nl(data); 
cout << data; // data = aaabbbcccddd
 1
Author: M.Kungla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-08 23:20:13

Utilice algoritmos std::. Esta pregunta tiene algunas sugerencias reutilizables Eliminar espacios de std:: string en C++

 0
Author: hplbsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:11
 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 );

O (elimina varias líneas nuevas al final)

some_str.resize( some_str.find_last_not_of(L"\n")+1 );
 0
Author: Kirill V. Lyadvinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:10:01

Si está en cualquier lugar de la cadena, no puede hacerlo mejor que O(n).

Y la única manera es buscar '\n' en la cadena y borrarla.

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

Para más líneas nuevas que:

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

Borra todas las nuevas líneas una vez.

 0
Author: csiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:29:44

Acerca de la respuesta 3 eliminando solo el último \n del código de cadena:

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

¿La condición if no fallará si la cadena está realmente vacía ?

No Es mejor hacer :

if (!s.empty())
{
    if (s[s.length()-1] == '\n')
        s.erase(s.length()-1);
}
 0
Author: Christophe Van Reusel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-06 09:36:45

Todas estas respuestas me parecen un poco pesadas.

Si simplemente remueve el '\n' y mueve todo lo demás hacia atrás, es probable que algunos personajes se peguen de una manera extraña. Entonces, ¿por qué no hacer lo simple (y más eficiente): Reemplazar todos los '\n's con espacios?

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

Puede haber formas de mejorar la velocidad de esto en los bordes, pero será mucho más rápido que mover trozos enteros de la cadena en la memoria.

 -1
Author: T.E.D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-28 19:22:36