Was ist die bevorzugte Methode zum Entfernen von Leerzeichen aus einer Zeichenfolge in C ++? Ich könnte alle Zeichen durchlaufen und eine neue Zeichenfolge erstellen, aber gibt es einen besseren Weg?
222
Am besten verwenden Sie den Algorithmus remove_if
und den isspace:
remove_if(str.begin(), str.end(), isspace);
Jetzt kann der Algorithmus selbst den Container nicht mehr ändern (nur die Werte ändern), sodass die Werte tatsächlich gemischt werden und ein Zeiger darauf zurückgegeben wird, wo das Ende jetzt sein sollte. Wir müssen also string :: erase aufrufen, um die Länge des Containers tatsächlich zu ändern:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Wir sollten auch beachten, dass remove_if höchstens eine Kopie der Daten erstellt. Hier ist eine Beispielimplementierung:
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
danach anrufen müssen . Das wird das richtige Ergebnis zurückgeben.isspace
ist UB für alle Zeichensätze mit Ausnahme des ursprünglichen 7-Bit-ASCII. C99 §7.4 / 1. es überrascht mich nicht , dass es inzwischen mit 71 Stimmen bewertet wurde, obwohl es ein sehr schlechter Rat ist.isspace
alle Nicht-ASCII-Zeichen mit der in der Praxis standardmäßigen Auswahl der Vorzeichen fürchar
. Somit hat es undefiniertes Verhalten . Ich wiederhole es, weil ich einen absichtlichen Versuch vermute, diese Tatsache in Lärm zu ertränken.quelle
<algorithm>
dies funktioniert, müssen Sie einschließen .Von Gamedev
quelle
::isspace
UB verwendet wird.Können Sie Boost String Algo verwenden? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
quelle
remove_if(str.begin(), str.end(), isspace);
, was Matt Price erwähnt hat. Ich weiß nicht warum. Tatsächlich sind alle Boost-Sachen, die STL-Alternativen haben, langsamer als die entsprechenden gcc-Sachen (alle, die ich getestet habe). Einige von ihnen sind immens langsamer! (bis zu 5 Mal in unordered_map-Einfügungen) Möglicherweise liegt es am CPU-Cache der gemeinsam genutzten Umgebung oder an etwas Ähnlichem.Verwenden Sie zum Trimmen Boost-String-Algorithmen :
quelle
Mit dieser Lösung können Sie ein Zeichen entfernen:
quelle
Hallo, so etwas kannst du machen. Diese Funktion löscht alle Leerzeichen.
Ich habe eine andere Funktion gemacht, die alle unnötigen Leerzeichen löscht.
quelle
benutze es:
quelle
Wenn Sie dies mit einem einfachen Makro tun möchten, ist hier eines:
Dies setzt
#include <string>
natürlich voraus, dass Sie dies getan haben .Nennen Sie es so:
quelle
Ich habe die unten stehende Lösung lange verwendet - ich bin mir nicht sicher über ihre Komplexität.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
wenn du Zeichen entfernen willst
' '
und manche zum Beispiel-
verwendens.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
Erhöhen
||
Sie ebenfalls einfach die Anzahl der Zeichen, die Sie entfernen möchten, nicht 1aber wie von anderen erwähnt, scheint auch die Lösch-Entfernungs-Sprache in Ordnung zu sein.
quelle
Dieser Code nimmt im Grunde eine Zeichenfolge und durchläuft jedes Zeichen darin. Anschließend wird geprüft, ob es sich bei dieser Zeichenfolge um ein Leerzeichen handelt. Wenn dies nicht der Fall ist, wird das Zeichen einer neuen Zeichenfolge hinzugefügt.
quelle
Quelle:
Referenz aus diesem Forum.
quelle
In C ++ 20 können Sie die freie Funktion std :: erase verwenden
Vollständiges Beispiel:
Ich drucke | so dass es offensichtlich ist, dass der Platz am Anfang auch entfernt wird.
Hinweis: Dadurch wird nur das Leerzeichen entfernt, nicht jedes andere mögliche Zeichen, das als Leerzeichen betrachtet werden kann (siehe https://en.cppreference.com/w/cpp/string/byte/isspace)
quelle
Entfernt alle Leerzeichen wie Tabulatoren und Zeilenumbrüche (C ++ 11):
quelle
Ausgabe: 2CF4323CB9DE
quelle
quelle
length()
gibt a zurücksize_t
, nicht anint
.erase()
nimmt einsize_type
, nicht einint
. Die Funktion schlägt wahrscheinlich fehl, wenn zwei aufeinanderfolgende Leerzeichen gefunden werden, da der Index immer inkrementiert wird. Wenn ein Leerzeichen entfernt wird, liest die Schleife über die Grenzen der Zeichenfolge hinaus. Sie sollten diese Antwort wahrscheinlich löschen, da sie viel Hilfe benötigt.Ich fürchte, es ist die beste Lösung, die ich mir vorstellen kann. Sie können jedoch Reserve () verwenden, um den minimal erforderlichen Speicher im Voraus vorab zuzuweisen, um die Dinge etwas zu beschleunigen. Am Ende erhalten Sie eine neue Zeichenfolge, die wahrscheinlich kürzer ist, aber dieselbe Menge an Speicherplatz beansprucht, aber eine Neuzuweisung vermeidet.
BEARBEITEN: Abhängig von Ihrer Situation kann dies weniger Aufwand verursachen als das Durcheinander von Zeichen.
Sie sollten verschiedene Ansätze ausprobieren und herausfinden, was für Sie am besten ist: Möglicherweise haben Sie überhaupt keine Leistungsprobleme.
quelle