Neue Memberfunktion für String
-
Doch , ich will nicht ständig
str = trim(str);, sondern
str.trim();und außerdem kann ich nicht
string trim(string& str) { while((str[0] == '\n') || (str[0] == ' ') || (str[0] == '\t')) str = str.substr(1); return str; }schreiben, da das mit soetwas wie " lol" nicht fertig wird. Und beide Überladen, geht auch nicht, da wenn ich eine Variable verwende, der Compiler sich nicht entscheiden kann!
-
Die erinnerung schrieb:
Doch , ich will nicht ständig
str = trim(str);, sondern
str.trim();Dann erb private von std::string und mach deine eigene Klasse.
und außerdem kann ich nicht
string trim(string& str) { while((str[0] == '\n') || (str[0] == ' ') || (str[0] == '\t')) str = str.substr(1); return str; }schreiben, da das mit soetwas wie " lol" nicht fertig wird.
Warum machst du deine Referenz dann nicht const?
Aber hier hast du dann gleich den Nachteil deiner eigenen Klasse. Du könntest nicht
" lol".trim()schreiben undmy_string(" lol").trim()macht auch nicht was du suchst. Selbst wenn du irgendwie std::string deine Funktion als Member hinzufügen könntest, wärestd::string(" lol").trim()immer noch nicht was du willst.Hingegen geht
std::string ergebnis = trim(" lol")ganz ohne Probleme.
-
Die erinnerung schrieb:
Doch , ich will nicht ständig
str = trim(str);, sondern
str.trim();Geht nicht, das musst du akzeptieren. Aber das wäre ohnehin nicht sinnvoll. In C++ hast du freie Funktionen zur Erweiterung von Funktionalität, dann sieht das so aus:
trim(str);Die erinnerung schrieb:
und außerdem kann ich nicht schreiben, da das mit soetwas wie " lol" nicht fertig wird.
Was für eine Begründung.
"lol".trim()geht genauso wenig. Warum überhaupt sollte man temporäre Objekte ändern wollen?
-
Ich glaube das Dürfte funktionieren:
#include <string> #include <iostream> using namespace std; string trim(string& str) { while((str[0] == '\n') || (str[0] == ' ') || (str[0] == '\t')) str = str.substr(1); return str; } string trim(string str) { while((str[0] == '\n') || (str[0] == ' ') || (str[0] == '\t')) str = str.substr(1); return str; } int main() { string str = " lol"; cout << trim(" lol") << endl << trim(&str) << endl << str << endl; return 0; }Oder was meint ihr?
-
Dass es nicht geht, hast du doch in schon selbst festgestellt.
Der Compiler wird dir das gerne noch einmal bestätigen.
-
string trim(string& str)hat eine merkwürdige Semantik. Willst du nicht ein Inplace-Trim und ein Kopier-Trim bereitstellen?
Das würde ich so tun:
void trim(std::string& str) { ... } std::string trim_copy(std::string str) { trim(str); return str; }
-
Die erinnerung schrieb:
Oder was meint ihr?
Wir meinen: Nimm NUR die zweite Variante, die erste macht dir dein Programm kaputt...
-
l'abra d'or schrieb:
Die erinnerung schrieb:
Oder was meint ihr?
Wir meinen: Nimm NUR die zweite Variante, die erste macht dir dein Programm kaputt...
0k. War nur ne Frage. Ich verwende im Moment eh nur die 2. Version im Programm.
-
Dann noch ein paar Tips wie du den Code optimieren kannst:
Kopien sind teuer. Deshalb solltest du das Argument auch per const-Referenz übergeben.
Auch substr() erzeugt eine Kopie -> teuer!
Speicher dir stattdessen einen "size_t currentIndex", den du immer hochzählst, solange str[currentIndex] ein Space ist. Gibt isspace false zurück, hast du deinen Index für substr. Dann hast du
Übergabe per Referenz (billig) Index inkrementieren (billig) und ein substr() - die teuerste Operation in der Funktion.
-
Und das ganze als Funktion für nichtFreaks, bitte?!?!?
-
l'abra d'or sagte, dass du alle Whitespacezeichen gleichzeitig mit einem einzigen Aufruf von substr wegmachen sollst und dass der Parameter eine konstante Referenz sein sollte, damit keine unnötige Kopie angefertigt wird.
War doch verständlich genug.
-
Beispielsweise
std::string trim_copy(std::string const &s) { std::string::size_type vorn = s.find_first_not_of(" \t\n"); if(vorn == std::string::npos) return ""; std::string::size_type hinten = s.find_last_not_of (" \t\n"); return s.substr(vorn, hinten - vorn + 1); }Allerdings gibt's das Ganze von boost schon hübscher (und mit Locale-Unterstützung): http://www.boost.org/doc/libs/1_45_0/doc/html/string_algo.html
-
std::string Trim( std::string & str ) { size_t trim; if( (trim = str.find_first_not_of( " \t" )) != string::npos ) str.erase( 0, trim ); if( (trim = str.find_last_not_of( " \t" )) != string::npos ) str.resize( trim+1 ); return( str ); }