Qual è il modo preferito per rimuovere gli spazi da una stringa in C ++? Potrei scorrere tutti i personaggi e creare una nuova stringa, ma c'è un modo migliore?
Qual è il modo preferito per rimuovere gli spazi da una stringa in C ++? Potrei scorrere tutti i personaggi e creare una nuova stringa, ma c'è un modo migliore?
Risposte:
La cosa migliore da fare è usare l'algoritmo remove_if
e isspace:
remove_if(str.begin(), str.end(), isspace);
Ora l'algoritmo stesso non può cambiare il contenitore (modifica solo i valori), quindi mescola i valori e restituisce un puntatore al punto in cui dovrebbe essere la fine. Quindi dobbiamo chiamare string :: erase per modificare effettivamente la lunghezza del contenitore:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Dobbiamo anche notare che remove_if eseguirà al massimo una copia dei dati. Ecco un'implementazione di esempio:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
seguito. Ciò restituirà il risultato corretto.
isspace
è UB per tutti i set di caratteri tranne ASCII originale a 7 bit. C99 §7.4 / 1. che non sorprende me che è stato upvoted per la somma di 71 voti, ormai, nonostante sia molto un cattivo consiglio.
isspace
, per tutti i caratteri non ASCII, con la scelta predefinita di firma per char
. Quindi ha un comportamento indefinito . Lo ripeto perché sospetto un tentativo deliberato di annegare questo fatto nel rumore.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
per farlo funzionare.
Da gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
è UB.
Puoi usare Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
erase_all(str, " ");
remove_if(str.begin(), str.end(), isspace);
quello menzionato da Matt Price. Non so perché. In realtà, tutte le cose boost, che hanno alternative STL, sono più lente di quelle corrispondenti gcc (tutte quelle che ho testato). Alcuni di loro sono immensamente più lenti! (fino a 5 volte negli inserti unordered_map) Forse è a causa della cache della CPU dell'ambiente condiviso o qualcosa del genere.
Per tagliare, utilizzare gli algoritmi di stringa di boost :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
È possibile utilizzare questa soluzione per rimuovere un carattere:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Ciao, puoi fare qualcosa del genere. Questa funzione cancella tutti gli spazi.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Ho fatto un'altra funzione, che cancella tutti gli spazi non necessari.
string delUnnecessary(string &str)
{
int size = str.length();
for(int j = 0; j<=size; j++)
{
for(int i = 0; i <=j; i++)
{
if(str[i] == ' ' && str[i+1] == ' ')
{
str.erase(str.begin() + i);
}
else if(str[0]== ' ')
{
str.erase(str.begin());
}
else if(str[i] == '\0' && str[i-1]== ' ')
{
str.erase(str.end() - 1);
}
}
}
return str;
}
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
size_t position = 0;
for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
{
str.replace(position ,1, toreplace);
}
return(str);
}
usalo:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Se vuoi farlo con una macro semplice, eccone una:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Questo presuppone che tu l'abbia fatto #include <string>
ovviamente.
Chiamalo così:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Ho usato a lungo il lavoro di seguito - non sono sicuro della sua complessità.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
quando vuoi rimuovere il personaggio ' '
e alcuni ad esempio lo -
usano
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
allo stesso modo aumenta solo il ||
numero di caratteri che vuoi rimuovere non è 1
ma, come detto da altri, anche la cancellazione rimuove il linguaggio sembra a posto.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Questo codice fondamentalmente prende una stringa e scorre attraverso ogni carattere in essa contenuto. Quindi controlla se quella stringa è uno spazio bianco, in caso contrario il carattere viene aggiunto a una nuova stringa.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Riferimento tratto da questo forum.
In C ++ 20 puoi usare la funzione gratuita std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Esempio completo:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Stampo | quindi è ovvio che anche lo spazio all'inizio è rimosso.
nota: questo rimuove solo lo spazio, non tutti gli altri possibili caratteri che possono essere considerati spazi bianchi, vedere https://en.cppreference.com/w/cpp/string/byte/isspace
Rimuove tutti i caratteri di spazi bianchi come schede e interruzioni di riga (C ++ 11):
string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
string str = "2C F4 32 3C B9 DE";
str.erase(remove(str.begin(),str.end(),' '),str.end());
cout << str << endl;
uscita: 2CF4323CB9DE
string removespace(string str)
{
int m = str.length();
int i=0;
while(i<m)
{
while(str[i] == 32)
str.erase(i,1);
i++;
}
}
length()
restituisce a size_t
, non an int
. erase()
prende un size_type
, non un int
. La funzione probabilmente fallirà se si incontrano due spazi consecutivi poiché l'indice è sempre incrementato. Se uno spazio viene rimosso, il ciclo leggerà oltre i limiti della stringa. Probabilmente dovresti eliminare questa risposta poiché ha bisogno di molto aiuto.
Temo sia la migliore soluzione che mi venga in mente. Ma puoi usare reserve () per pre-allocare la memoria minima richiesta in anticipo per velocizzare un po 'le cose. Ti ritroverai con una nuova stringa che sarà probabilmente più corta ma che occuperà la stessa quantità di memoria, ma eviterai le riallocazioni.
MODIFICA: A seconda della situazione, ciò potrebbe comportare meno costi generali dei personaggi confusi.
Dovresti provare approcci diversi e vedere cosa è meglio per te: potresti non avere alcun problema di prestazioni.