Domanda

Che cosa è il modo più efficace per la rimozione di una 'nuova linea' da uno std :: string?

È stato utile?

Soluzione

#include <algorithm>
#include <string>

std::string str;

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

Il comportamento di std :: remove non può essere del tutto ciò che vi aspettereste. Vedere una spiegazione di esso qui .

Altri suggerimenti

Se la nuova linea dovrebbe essere alla fine della stringa, quindi:

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

Se la stringa può contenere molti ritorni a capo in qualsiasi punto della stringa:

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

Si dovrebbe usare la erase-remove idioma , alla ricerca di '\n'. Ciò funzionerà per qualsiasi contenitore sequenza standard; non solo string.

Ecco uno per DOS o Unix nuova linea:

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

Il codice rimuove tutti a capo dal str stringa.

O (N) implementazione meglio servito senza commenti su SO e con commenti in produzione.

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

Un altro modo per farlo nel ciclo for

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

Utilizzo:

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

L'uso std :: algoritmi. Questa domanda ha alcuni suggerimenti opportunamente riutilizzabili Rimuovere gli spazi da 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 );

o (rimuove diverse a capo alla fine)

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

Se la sua in qualsiasi punto della stringa di quanto non si può fare meglio di O (n).

E l'unico modo è quello di cercare '\ n' nella stringa e cancellarlo.

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

Per maggiori ritorni a capo di:

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

Si cancella tutti i ritorni a capo una volta.

A proposito di risposta 3 rimuovere solo l'ultimo \ n No Stringa di codice:

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

Sarà il caso condizione non fallire se la stringa è veramente vuoto?

Non è meglio fare:

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

Tutte queste risposte sembrano un po 'pesante per me.

Se solo flat out rimuovere il '\ n' e spostare tutto il resto indietro di un punto, siete responsabili di avere alcuni caratteri sbattuto insieme in un modo strano aspetto. Allora perché non basta fare il semplice (e più efficace) cosa:? Sostituire all '\ n è con spazi

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

Ci possono essere modi per migliorare la velocità di questo ai bordi, ma sarà modo più veloce di spostare interi pezzi della stringa intorno in memoria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top