C ++ Rimuovere nuova linea da stringa multilinea
Domanda
Che cosa è il modo più efficace per la rimozione di una 'nuova linea' da uno std :: string?
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.