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?
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?
Antworten:
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ür char
. Somit hat es undefiniertes Verhalten . Ich wiederhole es, weil ich einen absichtlichen Versuch vermute, diese Tatsache in Lärm zu ertränken.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
dies funktioniert, müssen Sie einschließen .
Von Gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::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
erase_all(str, " ");
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 :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Mit dieser Lösung können Sie ein Zeichen entfernen:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Hallo, so etwas kannst du machen. Diese Funktion löscht alle Leerzeichen.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Ich habe eine andere Funktion gemacht, die alle unnötigen Leerzeichen löscht.
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);
}
benutze es:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Wenn Sie dies mit einem einfachen Makro tun möchten, ist hier eines:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Dies setzt #include <string>
natürlich voraus, dass Sie dies getan haben .
Nennen Sie es so:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
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 -
verwenden
s.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 1
aber wie von anderen erwähnt, scheint auch die Lösch-Entfernungs-Sprache in Ordnung zu sein.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
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.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Referenz aus diesem Forum.
In C ++ 20 können Sie die freie Funktion std :: erase verwenden
std::string str = " Hello World !";
std::erase(str, ' ');
Vollständiges Beispiel:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
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)
Entfernt alle Leerzeichen wie Tabulatoren und Zeilenumbrüche (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;
Ausgabe: 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()
gibt a zurück size_t
, nicht an int
. erase()
nimmt ein size_type
, nicht ein int
. 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.