Nabend,
Wie oben erwähnt würde Ich gerne aus einem String bestimmte Zeichen raus
löschen und die Zeichen die danach kommen, hinten an den String wieder
anfügen, so daß dort keine Leerzeichen entstehen.
Test String: Gutxxen Axxxbend
Ziel String: Guten Abend
Was macht man jetzt am besten? Man könnte es ja einfach umkopieren mit
ein paar abfragen in ein anderes Array..
Gibt es noch eine gute Alternative?
Unerwünschte Zeichen lösche ich meist mit der langen Taste üner der
Return Taste auf der Tastatur.
Wenn du willst, dass dies eine Software macht, musst du schon sagen
welche.
Du meine Güte, das ist doch nun wirklich keine Raketenwissenschaft.
Offensichtlich mußt du Zeichen für Zeichen durch den String gehen und
unerwünschte Zeichen überspringen. Du kannst noch überlegen, ob du das
Ergebnis in einen neuen String kopierst oder gleich den alten String
überschreibst.
Axel S. schrieb:> Du meine Güte, das ist doch nun wirklich keine Raketenwissenschaft.> Offensichtlich mußt du Zeichen für Zeichen durch den String gehen und> unerwünschte Zeichen überspringen. Du kannst noch überlegen, ob du das> Ergebnis in einen neuen String kopierst oder gleich den alten String> überschreibst.
Ich will den alten String benutzen. Möchte ihn aber nicht überschreiben.
Die Zeichen sollen gelöscht werden die unerwünscht sind und jeweils soll
kein Leerzeichen dazwischen stehen, also sollten die Zeichen die danach
kommen nach links verschoben werden.
Frank M. schrieb:> void remove_2 (char * str)> {> char * p;>> while (*str)> {> while (*str == 'x')> {> for (p = str; *p; p++)> {> *p = *(p + 1);> }> }> str++;> }> }
Und wenn Ich jetzt..
Guxten Txag
Das die x entfernt werden und der Text danach jeweils um eins verschoben
nach links rückt? Geht damit nicht?
Jan H. schrieb:> Das die x entfernt werden und der Text danach jeweils um eins verschoben> nach links rückt? Geht damit nicht?
Der Text wird doch nach links verschoben. Probiers einfach aus oder gehe
das Programm mit Bleistift und Papier schrittweise durch.
Ein wenig den eigenen Grips anstrengen muss man beim Programmieren (oder
beim Programm-Lesen) schon. Wenn Dich das jetzt überfordert, schnapp dir
ein C-Buch und arbeite es systematisch durch. Pointer sind nicht das
erste, was man bei C lernen sollte.
Dr. Sommer schrieb:> Das geht einfacher:
Einfacher gehts immer. Ich wollte eine möglichst auch für den Anfänger
gut lesbare und nachvollziehbare Möglichkeit aufzeigen. ;-)
Da der TO aber zerstöungsfrei kopieren möchte, ist remove_1() sowieso
die für ihn geeignetere Lösung.
Michael B. schrieb:> Das ist doch dasselbe wie remove_1, nicht bemerkt ?
Hmm stimmt, remove_2 ist wohl generell überflüssig, man kann remove_1
auch zweimal den gleichen Pointer übergeben sodass es in-place
arbeitet...
Dr. Sommer schrieb:> Hmm stimmt, remove_2 ist wohl generell überflüssig,
Ja, remove_2() sollte lediglich eine Alternative aufzeigen, die der TO
aber so gar nicht braucht, da er den Original-String nicht zerstören
möchte.
Jan H. schrieb:> Ich will den alten String benutzen. Möchte ihn aber nicht überschreiben.>> Die Zeichen sollen gelöscht werden die unerwünscht sind
Das widerspricht sich. Wenn du Zeichen im String löschst, dann
überschreibst du ihn doch?
@Frank M. & Co.
Helfersyndrom? Das ist ein wirklich triviales Problem. Wenn er das nicht
selber hinbekommt, dann bekommt er nie irgendwas hin.
Axel S. schrieb:> Das widerspricht sich. Wenn du Zeichen im String löschst, dann> überschreibst du ihn doch?
Einen String einlesen und einen anderen (geänderten) zurückgeben?
Nils P. schrieb:> void removeChars (char * input, const char *unwanted, char * output)> {> char * substring = strtok(input, unwanted);>> *output = 0;>> while(substring != NULL) {> strcat (output, substring);> substring = strtok(NULL, unwanted);> }> }
Die Funktion ist auch gut. Funktioniert einwandfrei.
Habe mich wahrscheinlich ein wenig undeutlich ausgedrückt.
Den String, den Ich absuchen möchte, soll bearbetiet werden. Das heißt
die Zeichen die dort in dem String vorkommen, die gesucht werden sollen
daraus entfernt werden.
Die Funktion von Frank M. erfüllt genau diesen Zweck. Ich werde mir
diese jetzt mal genauer anschauen, damit Ich es verstehe. Vielen Dank
für die Hilfe.
Jan H. schrieb:> Ich will den alten String benutzen. Möchte ihn aber nicht überschreiben.
Ein String braucht einen Puffer, also ein Stück Speicher, und einen
Pointer.
Wenn du den alten String erhalten willst, musst du ihn in einen neuen
Puffer kopieren. Wenn du den alten Puffer für den neuen String benutzen
willst, geht das nicht ohne ihn zu überschreiben.
Hier eine Funktion zum kopieren ohne die Zeichen im String without:
Zurückgegeben wird ein Zeiger auf die Null am Stringende, er kann
benutzt werden für das Anhängen von weiteren Strings oder Zeichen.
Du kannst die Kopierfunktion auch mit demselben Puffer verwenden, da der
Lesezeiger s entweder identisch mit dem Schreibzeiger t ist oder ihm
vorauseilt:
Das ist nur auf den ersten Blick eine einfache Sache.
Wird aus: "Gutxxen Axxxbend"
"xx" und "xxx" entfernt, so soll trotzdem NICHT aus:
"Text" -> "Tet" werden.
Auch ist "Axbend" nicht besonders schön, auch wenn vorher "Axxxxbend"
da stand.
Zugegeben, "xx" ist in der deutschen Sprache wohl nicht allzu häufig,
aber einfach über die Anzahl an Zeichen zu filtern, wird auch in die
Hose gehen.
Ob das überhaupt - ohne Wörterbuch - machbar ist, weiß ich nicht. Aber
allzu viel Info hat der TO ja auch nicht rübergebracht.
Sebastian S. schrieb:> Wird aus: "Gutxxen Axxxbend"> "xx" und "xxx" entfernt, so soll trotzdem NICHT aus:> "Text" -> "Tet" werden.
Ich nehme doch stark an, dass der TO das 'x' nur als ein exemplarisches
Beispiel genommen hat, welches mit der tatsächlichen Aufgabe in der
Realität gar nichts zu tun hat. Von daher sind Deine Folgerungen reine
Spekulation.
Nils P. schrieb:> void removeChars (char * input, const char *unwanted, char * output)> {> char * substring = strtok(input, unwanted);>> *output = 0;>> while(substring != NULL) {> strcat (output, substring);> substring = strtok(NULL, unwanted);> }> }
Diese Funktion ist ohne Not O(n²) statt O(n).
Ist bei kurzen Texten sicher egal, und mag elegant zu tippen sein, aber
grade bei so Anfänger-Fragen sollte man dazuschreiben, dass diese
Funktion um Welten schlechter ist als die anderen Vorschläge.
Sonst passiert sowas:
Jan H. schrieb:> Die Funktion ist auch gut.
Nein. Sie ist eine ganz Kategorie schlechter als die anderen.
@Frank
>Ich nehme doch stark an, dass der TO das 'x' nur als ein exemplarisches>Beispiel genommen hat, welches mit der tatsächlichen Aufgabe in der>Realität gar nichts zu tun hat. Von daher sind Deine Folgerungen reine>Spekulation.
Dann erst recht!
So kommen die Buchstaben "s" oder "f" bis zu 3-mal in einem Wort vor,
ohne das der Herr Duden darüber meckert.
Aber worauf ich hinaus will ist: Es ist, ohne den gesamten Text im Auge
zu behalten gefährlich, irgend welche Buchstabenkombinationen - ohne
Quittung - zu ersetzen.
Leider kann Ich hier nicht so viele "Zitatzeilen" einfügen.
Ich spreche das Beispiel von Frank M. (remove_2) an...
Jetzt muss Ich doch eine Frage los werden.. Was genau macht der Zeiger
"*p" wenn er nicht zurück gegeben wird? Und wieso wird "*str" richtig
zurückgegeben wenn dieser gar nicht bearbeitet wird?!
Wenn alle dürfen, dann ich auch. Die Funktion kopiert den String auf
sich selbst und überspringt dabei alle Vorkommen des unerwünschten
Zeichens. Da der Zielstring nicht länger sein kann als das Original,
geht das immer.
Ich habe versucht, es sowohl kompakt als auch lesbar zu formulieren.
Jan H. schrieb:> Jetzt muss Ich doch eine Frage los werden.. Was genau macht der Zeiger> "*p" wenn er nicht zurück gegeben wird? Und wieso wird "*str" richtig> zurückgegeben wenn dieser gar nicht bearbeitet wird?!
Du meinst:
1
for(p=str;*p;p++)
2
{
3
*p=*(p+1);
4
}
Der Pointer p läuft von der Stelle los, an der str gerade steht und
"zieht" die Zeichen, die rechts davon stehen, um eine Stelle nach links.
Die for-Schleife wird beendet, wenn der String zu Ende ist.
Beispiel: "abcxdef" im RAM untereinander geschrieben:
1
a
2
b
3
c
4
x <--- da steht im Moment str und damit auch p wgen for (p = str;...)
5
d
6
e
7
f
8
\0 Hier ist der String zu Ende
Wegen *p = *(p + 1) wird nun das d an die Stelle von x kopiert, e an die
alte Stelle von d, f an die alte Stelle von e. Als letztes wird noch der
String-Terminator \0 nach links kopiert. Nach Durchlauf der for-Schleife
steht dann im RAM:
1
a
2
b
3
c
4
d <--- da steht immer noch str
5
e
6
f
7
\0 Nun ist der String-Terminator eine Stelle weiter links
8
\0 Der alte String-Terminator, hier steht jetzt p
Damit wurde das x eliminiert und der Teilstring "def" inkl. Terminator
ist um eine Stelle nach links gewandert.
Deine Frage zeigt, dass Du noch waschechter Anfänger bist. Ich gebe Dir
nochmal den Tipp, ein C-Buch systematisch durchzuarbeiten. Man kann
keine Programmiersprache in einem Forum lernen. Außerdem sind Pointer
bei einem C-Kurs erst dran, wenn man die Basis bereits gelernt hat.
Anpassungen:
1) es braucht keinen Rückgabewert
2) es braucht nur einen Pointer (s1 = s2)
3) es braucht ein zu entfernendes Zeichen (int c)
4) umdrehen auf do while, damit keine Sonderbehandlung für abschließende
0
5) Sicherstellen, dass c==0 nichts schlimmes macht (was immer auch dann
passieren sollte)