Funktion zur Stringbearbeitung
-
Ich habe eine Funktion geschrieben welche einen String der Form
" bla blub = blubbb bla "
in einen String in der Form
"bla blub=blubbb bla"
umwandelt.
Diese Funktion kommt mir jedoch etwas groß und umständlich vor, gibt mit Hilfe der STL ne kürzere/bessere Methode das zu realisieren?
meine Funktion sieht so aus:
void StripSpaces( std::string& str ) { //string anfang bis erstes zeichen std::string::iterator mark1 = str.begin(); while( !std::isalpha( *( mark1 + 1 ) ) ) ++mark1; str.erase( str.begin(), mark1 + 1 ); //letztes Zeichen bis = mark1 = str.begin() + str.find( '=' ); std::string::iterator mark2 = mark1; while( std::isspace( *( mark2 - 1 ) ) ) --mark2; str.erase( mark2, mark1 ); //von = bis zun ersten Zeichen mark1 = str.begin() + str.find( '=' ); mark2 = mark1; while( std::isspace( *( mark2 + 1 ) ) ) ++mark2; str.erase( mark1 + 1, mark2 +1 ); //vom letzten Zeichen bis zum Ende std::string::reverse_iterator mark3 = str.rbegin(); while( std::isspace( *( mark3 + 1 ) ) ) ++mark3; str.erase( mark3.base() - 1, str.rbegin().base() ); }
-
das sieht doch eher nach einem Automaten-Problem aus. Schau Dir mal boost.Spirit unter http://www.boost.org/libs/spirit/index.html an.
Wenn Du's selber programmieren möchtest, sähe das vielleicht so aus. Diese Funktion stürzt jedenfalls nicht ab, wenn links oder rechts vom '=' keine Zeichen stehen.
#include <iostream> #include <string> void StripSpaces( std::string& txt ) { using namespace std; std::string::iterator lbeg = txt.begin(); std::string::iterator lend = txt.begin(); std::string::iterator rbeg = txt.end(); std::string::iterator rend = txt.end(); int state = 1; for( std::string::iterator i = txt.begin() ; i != txt.end(); ++i ) { switch( state ) { case 1: // kein nicht-Space if( *i == '=' ) { state = 3; } else if( !isspace( *i ) ) { lbeg = i; lend = i; state = 2; } break; case 2: // linkes nicht-Space, aber kein '=' if( *i == '=' ) { state = 3; } else if( !isspace( *i ) ) { lend = i+1; } break; case 3: // '=' gefunden noch kein nicht-Space rechts if( !isspace( *i ) ) { rbeg = i; rend = i+1; state = 4; } break; case 4: // rechtes nicht-Space gefunden if( !isspace( *i ) ) { rend = i+1; } break; } } txt = std::string( lbeg, lend ) + '=' + std::string( rbeg, rend ); } void show( std::string txt ) { using namespace std; cout << " |" << txt << "| -> |"; StripSpaces( txt ); cout << txt << "|" << endl; } int main() { show( " bla bla = kkl k--l " ); show( "kl=kl kl" ); show( " vorne= " ); show( " " ); show( "volltext" ); show( "=kl kl " ); show( "" ); show( " kl kl " ); return 0; }.. oder so ähnlich. Ich weiß nicht so viel von Automaten programmieren.
Zugegebener Maßen - ist auch groß
Gruß
Werner
-
/Edit: Müll
-
Du hast recht, da hab ich ja überhaupt keine Fehlerprüfung drin, wobei ich eigentlich von korrekter Eingabe ausgehen kann, aber man sollte es trotzdem überprüfen.
Ist boost::spirit dafür wirklich das richtige?
-
Bin zwar gerade dabei die STL zu lernen, aber habe mich mal trotzdem an dein Problem rangewagt, weil sie ja direkt ne Übungsaufgabe für mich ist

Ich habe nur nicht so strikte Fehlerprüfungen wie Werner gemacht, da ich davon ausgehe das die Strings immer ein "=" enthalten !
void StripSpaces( std::string& str ) { int a = str.find("="); if(a!=string::npos) { string links,rechts; links.assign(str,0,a); rechts.assign(str,a+1,str.size()); if(links[0]==' ') links.assign(links,1,links.size()); if(links[links.size()-1]==' ') links.assign(links,0,links.size()-1); if(rechts[0]==' ') rechts.assign(rechts,1,rechts.size()); if(rechts[rechts.size()-1]==' ') rechts.assign(rechts,0,rechts.size()-1); str.clear(); str=links + "=" + rechts; } }Auserdem ist meine Funktion schöner als deine und die von Werner
:p :p

-
Hiho,
genau diese Idee hatte ich auch als ich heute Morgen aufgestanden bin, aber danke so spar ich mir die Schreibarbeit
-
Ws sind denn das für Funktionen? Die Aufgabenstellung ist doch nur ein Dreizeiler.
-
Michael E. schrieb:
Ws sind denn das für Funktionen? Die Aufgabenstellung ist doch nur ein Dreizeiler.
Wäre dann mal Cool das du uns die auch zeigst, damit wir was lernen können, mal sehen ob du meiner 10 monatigen C++ Erfahrung was vormachen kannst

-
Fragesteller schrieb:
wobei ich eigentlich von korrekter Eingabe ausgehen kann,
Wenn das so ist dann reicht auch das:
void StripSpaces( std::string& str ) { str = str.assign(str,1,str.size()-2); str.erase(str.find("=") - 1,1); str.erase(str.find("=") + 1,1); }Extra in 3 Zeilen für Daniel

-
Freak_Coder schrieb:
Fragesteller schrieb:
wobei ich eigentlich von korrekter Eingabe ausgehen kann,
Wenn das so ist dann reicht auch das:
void StripSpaces( std::string& str ) { str = str.assign(str,1,str.size()-2); str.erase(str.find("=") - 1,1); str.erase(str.find("=") + 1,1); }Diese Funktion erfüllt aber nicht die an sie gestellte Aufgabe :p.
Caipi
-
Sorry, hab ich gar nicht dran gedacht in der Hektik.
Um den ersten String " bla blub = blubbb bla " in den String "bla blub=blubbb bla" umzuwandeln, reicht schon diese Funktion:
void StripSpaces(string &str) { str.erase(0, str.find_first_not_of(" ")); str.erase(str.find_last_not_of(" ") + 1); while(str.find(" = ") != string::npos) str.replace(str.find(" = "), 3, "="); }Natürlich ist sie nicht optimal, weil str.find() zwei Mail aufgerufen wird (wobei ich mir nicht sicher bin, ob das nicht wegoptimiert werden kann). Aber es ging ja jetzt um die Länge und schneller als eure Funktionen dürfte das hier schon sein.
-
Freak_Coder schrieb:
Extra in 3 Zeilen für Daniel

Meinst du mich?
-
Caipi schrieb:
Diese Funktion erfüllt aber nicht die an sie gestellte Aufgabe :p.
Hmmm, Echt ???
Bei mir tut sie es, es sei denn ich habe die Aufgabenstellung nicht verstanden...
Was macht sie denn falsch ???
-
@Michael E. : Upps

Wie kommt den Daniel her
Meinte natürlich dich 
-
Vielleicht assoziierst du E. mit Daniel E.
-
Zu deiner Funktion: Sie sollte auch noch hier funktionieren: "foo bar = blubb = bla ".
-
Freak_Coder schrieb:
Caipi schrieb:
Diese Funktion erfüllt aber nicht die an sie gestellte Aufgabe :p.
Hmmm, Echt ???
Bei mir tut sie es, es sei denn ich habe die Aufgabenstellung nicht verstanden...
Was macht sie denn falsch ???
Ich habe - beim ersten Überfliegen des Textes - die Funktion so verstanden, dass sie folgenden String
[b]"[/b] <variable_anzahl_leerzeichen_> bla blub <variable_anzahl_leerzeichen_> = <variable_anzahl_leerzeichen_>blub blaaaaa <variable_anzahl_leerzeichen_>[b]"[/b]in einen String der Form
[b]"[/b]bla blub=bla bluuuuuuub[b]"[/b]umwandeln soll, so dass die Anführungszeichen erhalten bleiben.
(Habe nämlich den Code des OP beim ersten Überfliegen mir nicht angeschaut [...])Sorry, mein Fehler...
Caipi
-
Michael E. schrieb:
Zu deiner Funktion: Sie sollte auch noch hier funktionieren: "foo bar = blubb = bla ".
Ja, wenn man davon nicht ausgeht das ein falscher String übergeben wird, aber wie ich schon geschrieben habe gilt die Funktion nur für die "korrekten" Strings...
Ansonsten würde ja meine 1. Funktion gelten, aber die ist ja im gegensatz zu deiner nen kleines Spielkind

jetzt habe ich immerhin noch 2 neue find() funktionen (durch deine func()) kennengelernt, komisch wie konnte ich die in der Reference übersehen haben
Achja, stimmt da gibts ja noch ein Daniel E. :p Bestimmt deswegen.
-
@Caipi: Tatsächlich, es wird nur das erste Vorkommen von " = " berücksichtigt.
Freak_Coder: Gib mal bitte ein Beispiel, bei der meine ein Problem hat. Meinst du etwas so was: "foo= bar"?
[EDIT] Wenn ja, dann macht das durch die getrennte Berücksichtigung von "= " und " =" noch eine Zeile mehr.
-
Gib mal bitte ein Beispiel, bei der meine ein Problem hat.
--> Hab ich das irgendwo behauptet

@Michael: Ich glaube wir verstehen uns irgendwie falsch. Ich meinte ja das deine Funktion ja eh besser als meine 1. ist.

Wenn man davon ausgeht das ne variable anzahl von Leerzeichen am Anfang am Ende und am Gleichheitszeichen sein kann