[Frage] bestimmte Zeichen aus Zeichenkette entfernen?
-
Hallo,
ich will gerne ein Zeichen (zB '*') aus einer Zeichenkette entfernen.
Es soll kein Leerzeichen gemacht werden, sondern das Zeichen komplett aus der Zeichenkette gelöscht werden.Beispiel:
vorher: "*** hallo **"
entfernen(s, ''); // das soll der Aufruf der Funktion sein, die meinen Wunsch erledigen soll.
nachher: " hallo "ich will es nicht mit s.erase machen, ich will meine eigene Funktion dafür haben!
Ich habe es schon auf viele verschiedene Wege versucht. Nichts klappt: Entwerder es sieht nachher so aus: "~~~ hallo ~~~" oder der Compiler meckert rum! Das Internet habe ich auch nach Hilfe durchsucht. Überall wird s.erase vorgeschlagen.
Bitte um Hilfe!
MfG, meldino.
-
Eine moegliche Loesung waere:
void my_erase( const char *str, char *erased_str, const char char_to_erase ) { int i, j, ch; i = j = 0; while ( (ch = str[i++]) != '\0' ) if ( ch != char_to_erase ) erased_str[j++] = ch; erased_str[j] = '\0'; }
'str' ist der String, aus dem 'char_to_erase' entfernt werden soll. Der String ohne 'char_to_erase' ist dann 'erased_str'.
Du kannst den Code z.B. folgendermassen aufrufen:
int main() { const char *s = "***He**llo***"; char erased[100]; my_erase( s, erased, '*' ); printf("%s\n", erased); }
Ich hoffer, dass der Code selbsterklaeren ist. Wenn nicht, dann frag ruhig nach. Eventuell gibt es auch noch bessere Loesungen. Ist einfach gerade die, die mir als erstes eingefallen ist.
*Edit
Eine weitere Moeglichkeit, in der mann keinen zweiten string braucht waere folgende:void my_erased2 ( char *str, const char char_to_erase ) { int i, j, ch; i = j = 0; while ( (ch = str[i++]) != 0 ) if ( ch != char_to_erase ) str[j++] = ch; str[j] = '\0'; }
Du kannst dann die Funktion z.B. so verwenden:
int main() { char s[] = "***He**llo***"; my_erased2( s, '*' ); printf("%s\n", s); }
-
Erstmal Danke für deine (schnelle) Antwort, icarus2!
Leider komm ich bei deinem Vorschlag nicht mit.
Mein Quellcode zurzeit:
void Str_RTrimChars (char *s, char ch); #include <stdio.h> #include <string.h> int main(void) { char s[] = "*** hallo ***"; printf ("vorher: \"%s\"", s); Str_RTrimChars (s, '*'); printf ("nachher: \"%s\"", s); getchar(); return 0; } void Str_RTrimChars (char *s, char ch){ int i; for(i=0; s[i] != '\0'; i++){ if(s[i]==ch) s[i]= // ab hier weiss ich nicht mehr weiter. } }
Der Aufruf MUSS zwei Parameter haben.
Ist das irgendwie möglich?MfG, meldino.
-
Ich habe deinen Code mal etwas abgeaendert, so dass er funktioniert:
void Str_RTrimChars (char *s, char ch){ int i; int j = 0; // Der Index an dem du schreibst for( i = 0; s[i] != '\0'; i++ ) { // Falls an der Stelle 'i' nicht 'ch' steht, schreibe s[i] an die Stelle j // Falls an der Stelle 'i' der Character 'ch' steht, dann uebersprignge diese Position if( s[i] != ch ) { s[j] = s[i]; // Schreibe s[i] an die Stelle 'j' j++; // Gehe mit j eins weiter nach rechts } } s[j] = '\0'; // Terminiere den String }
Das Prinzip ist, dass du an der Stelle i liest und an der Stelle j schreibst. Du beginnst bei i = 0 zu lesen. Wenn an der Stelle i nicht ch steht, dann schreibst du ch an der Stelle j und gehts eins nach rechts weiter. Falls an der Stelle i der Charakter ch steht, dann gehst du weiter beim lesen, schreibst aber nichts und der Schreibindex j bleibt.
Ich hoffe meine Erklaerung und der Code ist einigermassen verstaendlich.
-
Danke, vielen Dank, es funktioniert!
Leider verstehe ich aber (teilweise) nicht wieso.
Also:
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
' '- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'h'- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'a'- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'l'- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'l'- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'o'- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
' '- Position wird nicht übersprungen. Stelle j wird gleich Stelle i. Eine Stelle weiter rechts.
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
'*' - Position wird übersprungen. Eine Stelle weiter rechts.
zu Schluss wird String beendet. (terminiert)das heisst:
s[j] wird dann im Hauptprogramm ausgegeben?EDIT: nochmals vielen Dank! Ich bin dir sehr dankbar für deine Mühe!!
-
Ich glaube du hast etws noch falsch verstanden (bin mir aber nicht sicher), denn du sagst "Stelle j wird gleich Stelle i.". Das muss nicht sein, es gilt bloss i <= j.
Ich versuchs mal anhand eines Beispiels zu erklaren:
Nehmen wir folgendes an:
char s[] = "Ha";
char ch = '';i = 0
j = 01. Durchlauf
Du liest s[0] und siehst, dass s[0] != ch ist, das heisst du schreibst s[j] = s[i] (d.h. s[0] = s[0]). j wird erhoeht und i wird erhoeht, das heisst du hast nun folgendes:
i = 1
j = 1
s = "H*a"2. Durchlauf
Du liest s[1] und siehst, dass s[1] == ch ist. Das heisst du schreibst nichts, du erhoehst j NICHT, sondern nur i. Das heisst du hast
i = 2
j = 1
s = "H*a"3. Durchlauf
Du liest s[2] und siehst, dass s[2] != ch ist. Das heisst du schreibst s[j] = s[i] (d.h. s[1] = s[2]). Dann erhoehst du j um eins und i um eins. Dann hast du
i = 3
j = 2
s = "Haa"Die Schleife bricht nun ab und du terminierst den String an der Stelle j, d.h. du schreibst s[j] = '\0' (d.h. s[2] = '\0'). Dann hast du
i = 3
j = 2
s = "Ha" (In wirklichkeit steht da s = "Ha'\0'".Ist es nun klar, was passiert?
*Edit
Falls es dir noch nicht klar sein sollte, dann nimm einmal einen Block und ein Bleistift, suchst dir ein Beispiel, z.B. char s[] = "**Hall**0", und dann gehst du auf dem Blatt von Hand Schritt fuer Schritt den Algorithmus durch. Dann siehst du genau was passiert.
Das ist oftmals eine gute Moeglichkeit einen Algorithmus zu verstehen.
-
Bist du dir da beim 3. Durchlauf sicher dass s gleich Haa ist? oder Ha?
Grüße, meldino
-
Da steht "Haa". Der String wird nicht wirklich verkuerzt vom Speicher her gesehen. Zum Beispiel bei "Hallo***" hast du am Ende den String "Hallo'\0'**". Das heisst der String wurde vom Speicher, den er braucht nicht verkuerzt. Es wurden lediglich die Zeichen, die entfernt werden sollen, ueberschrieben und alles hinter dem '\0' ist Muell, den man nicht mehr braucht.
-
Okay, jetzt (glaub ich jedenfalls) hab ichs verstanden.
Danke dir!