Strings Buchstaben vertauschen



  • Guten Tag,

    da ich erst vor Kurzem mit der Programmierung anfangen habe, bräuchte ich bei einigen Aufgaben noch etwas Hilfe, um mein Wissen zu vergrößern und zu vertiefen.
    Gerade bleibe ich bei einer Aufgabe hängen, bei der in einem Text die Buchstaben in der Zeichenkette vertauscht werden sollen. In dem Text soll 'en' zu 'x' werden, 'x' zu 'en', 'y' zu 'ch' und umgekehrt, sowie 'er' zu 'q' und 'a' zu 'e', sowie ebenfalls umgekehrt. (Der Text braucht keinen Zusammenhang haben, es sollten einfach alle Tauschoptionen vorkommen.)
    Bei meiner vorherigen Aufgabe sollte ich das 'e' aus dem Text entfernen ohne Leerschlag, sodass die Zeichen einfach kürzer werden. Davon habe ich den Grundsatz übernommen und etwas umgeschrieben, funktioniert allerdings nicht...
    Vielen lieben Dank schon einmal im Voraus!!!
    Liebe Grüße Lea🙂

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main()
    {
        printf("3. Variante\n");                                                    // 3. Variante
    
        char string3[] = "Hallo, diese Nachricht wird ersetzt. Dieser Quelltext gehoert zu den Systemen.";
        char *zei;
        int k;
    
    
        printf("Vorher: %s\n", string3);                                            // Vorher
    
        for(k=0; string3[k]!='\0'; k++)                                             // Zeichen tauschen en&x, er&q,  y&ch, a&e
        {
            if(string3[k]=='en')
            {
                zei = &string3[k]='x';
                strcat(string3, zei);
            }
        }   printf("Nachher: %s\n\n", string3);                                     // Nachher
    
    
        //||string3[k]=='x'||string3[k]=='er'||string3[k]=='q'||string3[k]=='y'||string3[k]=='ch'||string3[k]=='a'||string3[k]=='e'   // Tauschoptionen für später
    
        return 0;
    }
    


  • @codinglea sagte in Strings Buchstaben vertauschen:

    funktioniert allerdings nicht.

    ist keine Fehlerbeschreibung.



  • Bei dem Wort "Systemen", sollte das 'en' zu 'x' werden, sodass das Ergebnis "Systemx" lautet.



  • @codinglea sagte in Strings Buchstaben vertauschen:

    Guten Tag,

    da ich erst vor Kurzem mit der Programmierung anfangen habe, bräuchte ich bei einigen Aufgaben noch etwas Hilfe, um mein Wissen zu vergrößern und zu vertiefen.
    Gerade bleibe ich bei einer Aufgabe hängen, bei der in einem Text die Buchstaben in der Zeichenkette vertauscht werden sollen. In dem Text soll 'en' zu 'x' werden, 'x' zu 'en', 'y' zu 'ch' und umgekehrt, sowie 'er' zu 'q' und 'a' zu 'e', sowie ebenfalls umgekehrt. (Der Text braucht keinen Zusammenhang haben, es sollten einfach alle Tauschoptionen vorkommen.)
    Bei meiner vorherigen Aufgabe sollte ich das 'e' aus dem Text entfernen ohne Leerschlag, sodass die Zeichen einfach kürzer werden. Davon habe ich den Grundsatz übernommen und etwas umgeschrieben, funktioniert allerdings nicht...

    Tipp: Teile die Aufgaben in kleinere Unteraufgaben.
    Zum Beispiel funktioniert if(string3[k]=='en') nicht, weil string3[k] exakt ein char zurückgibt, aber 'en', tja, was eigentlich ist? Ein String nicht, der wäre ja in Doppelquotes. Es ist ein Multi-Character Character Constant, 'en' == 25966 (in ASCII wegen e=101 und n=110 und 101*256+110=25966). Das ist nicht, was du willst. Die gesuchte Funktion, die einen String in einem anderen sucht, heißt strstr. Zu Übungszwecken schreib sie dir auch gerne erstmal selbst.

    Dann gehst du ans Ersetzen. Für den Fall, dass der Stirng länger werden kann, müsst du dir auch überlegen, wie du das mit dem Speicher machen willst. Willst du inplace ersetzen oder eine Kopie zurückgeben? Wenn inplace, musst du wissen, wie groß der Speicher maximal sein darf. Ansonsten gibt es mehrere Strategien. Zum Beispiel erstmal die Vorkommen zählen, damit du den benötigten Speicher kennst und im zweiten Schritt kopieren/ersetzen. Oder eben einen "groß genugen" Puffer von außen übergeben (inklusive size) und in diesen reinschreiben. Das ist die schöndere Variante, weil ersetzen dann keine Zweitaufgabe "Speicherbehandlung" hat.



  • Das ist, was du erwartest. Was ist das, was statt dessen passiert?



  • @wob
    Vielen Dank für die Hilfe! Ich werde es mit strstr ausprobieren!



  • @wob würde das nicht schneller gehen mit der Swap-Methode?



  • @codinglea Schreib gleich eine eigene Funktion und benutze main nur zum testen (aufrufen deiner Funktion)

    Bei der gewählten Definition von string3 bleibt kein Platz für zusätzliche Zeichen.

    @codinglea sagte in Strings Buchstaben vertauschen:

            zei = &string3[k]='x';
    

    Was soll das machen?
    xist ein Zeichen, zei ist ein Pointer, &string3[k] liefert eine Adresse (das passt zu zei)
    'x' und "x" sind zwei Verschiedene Sachen.

            strcat(string3, zei);
    

    Dies fügt am Ende von string3 den String zei an.
    Dafür ist kein Platz.



  • @DirkB
    Wie meinst du das? Wieso ist da kein Platz für zusätzliche Zeichen?🤔



  • @codinglea Du definierst das Array string3 ohne Längenangabe.

    Der Compiler ermittelt die Länge aus dem Initialisierungsstring.

    char string3[] = "Hallo, diese Nachricht wird ersetzt. Dieser Quelltext gehoert zu den Systemen.";
    

    Hat 78 Zeichen plus den Terminator '\0'.

    Wenn du ein x durch 2 Zeichen ersetzen willst, muss das Array größer werden.
    Das geht in C aber nicht.

    Ein Array ist nach seiner Definition in Größe und Ort (Adresse) festgelegt.

    Du kannst das umgehen, indem du das Array groß genug anlegst (oder mit dynamischer Speicherverwaltung).



  • @DirkB
    Ahh, vielen Dank! Habe es zu string3[100] geändert!


  • Mod

    @codinglea sagte in Strings Buchstaben vertauschen:

    @DirkB
    Wie meinst du das? Wieso ist da kein Platz für zusätzliche Zeichen?🤔

    Weil Arrays in C nicht änderbar sind. string3 ist aufgrund seiner Definition genau groß genug, um "Hallo, diese Nachricht wird ersetzt. Dieser Quelltext gehoert zu den Systemen." aufzunehmen (inklusive dem darin inbegriffenem \0 als Abschluss). Kein Zeichen mehr, kein Zeichen weniger, und das kann man auch nie wieder ändern.

    Wenn du mit längenveränderlichen Zeichenketten (oder Arrays allgemein) arbeiten möchtest, dann musst du eine Indirektion einführen. Das heißt, du zeigst nur auf ein Array und dieser Zeiger "ist" dann deine Zeichenkette. Dann kannst du nach Bedarf kürzere oder längere Arrays erzeugen und den Zeiger jeweils darauf zeigen lassen. So ändert sich dann effektiv die Länge der Zeichenkette, weil der Zeiger auf unterschiedlich große Arrays zeigt.

    Das ist aber nicht so ganz einfach und man kann viel falsch machen dabei. Unangenehmerweise funktioniert auch falscher Code oft trotzdem, bis man ihn dann live dem Lehrer vorführt. Du musst die nötigen Konzepte daher unbedingt grundlegend verstehen und darfst nicht einfach nur rumraten und probieren, bis es scheinbar irgendwie funktioniert. Richtig ist es nur, wenn du selber verstehst wie das mit den Zeigern und Arrays funktioniert und von einem Stück Code überzeugt sagen kannst, dass er so richtig ist.



  • @Luckyingmar sagte in Strings Buchstaben vertauschen:

    @wob würde das nicht schneller gehen mit der Swap-Methode?

    Würde WAS schneller gehen mit WELCHER Swap-Methode?
    Worauf beziehst du dich? Was ist die Swap-Methode? Unter swap verstehe ich das Vertauschen von 2 gleichartigen Dingen. "en" ist ein 2-Buchstaben-String und "x" ein 1-Buchstaben-String (oder 'x' ein Buchstabe) - die kann ich nicht swappen. Also String und String könnte man schon swappen, aber nicht Substring eines Strings mit einem String.



  • @wob achso ja gut dann hat sich das erledigt.



  • So, ich habe etwas rum probiert, doch ich komme jetzt nicht mehr weiter...
    Ich habe die Funktion strstr eingebaut, allerdings weiß ich nun nicht, wie ich das 'en' ersetze mit 'x'. Mit der Replace-Methode würde ich ja viel zu lang werden an Zeilen. 🤔
    Wie kann ich nun das gefundene 'en' von strstr umwandeln?



  • @codinglea sagte in Strings Buchstaben vertauschen:

    Mit der Replace-Methode würde ich ja viel zu lang werden an Zeilen.

    Manchmal muss man auch Code schreiben.

    Wie kann ich nun das gefundene 'en' von strstr umwandeln?

    An die Stelle vom e (da zeigt der Rückgabewert von strstr hin) ein 'x' schreiben und den Rest vom String um eine Stelle nach links verschieben.
    (Das geht mit einer Schleife oder mit der Funktion memmove)



  • @DirkB
    Na ja, meine Aufgabe besteht darin, den Code ziemlich kurz zu halten bei solchen "kleinen" Aufgaben...
    Okay, vielen Dank! Ich probiere es direkt aus. 🙂


  • Mod

    Und aufpassen, denn es kann ja auch umgekehrt sein, dass die neue Zeichenkette länger ist als die alte Zeichenkette.

    So ganz allgemein ist das schon halbwegs fortgeschrittener Stoff. Nicht ohne Grund, gibt es in der Standardbibliothek keine allgemeine Stringersetzungsfunktion. Denn beim Ersetzen von Teilzeichenketten durch Ketten anderer Länge muss man ungeheuer aufpassen und eine Menge Annahmen machen, die nicht unbedingt offensichtlich sind. Doch du scheinst (nichts für ungut), doch relativ planlos zu sein, was C-Strings angeht. Bist du sicher, dass du die Aufgabe richtig verstanden hast? Die ist nämlich viel zu schwer für den Kenntnisstand, der bei dir durchblickt (sie ist sogar so schwer, dass ich hier nicht einmal eine allgemeine Lösung demonstrieren möchte, weil es mir zu anstrengend wäre). Falls du dir die Aufgabe selbst gestellt hast: Such dir etwas einfacheres! Eine gute Standardaufgabe um mit Zeichenketten fit zu werden, ist das Nachprogrammieren der Funktionen aus string.h. Und wenn du die alle locker aus dem Handgelenk schütteln kannst, dann bist du bereit für eine allgemeine Ersetzungsfunktion.



  • Buchstabenmanipulationen (Zeichenketten)
    Schreiben Sie die folgenden kleinen Programme. Alle erwarten einen String, bestehend aus einigen Sätzen. Schreiben Sie zunächst also ein Hauptprogramm, das einen längeren Text mit Leerschlägen und Sonderzeichen als String oder char[]-array enthält oder vom Anwender erfragt (scan).
    auspressen(): Schreiben Sie eine Methode, die aus dem Text alle Buchstaben 'e' entfernt. Dabei werden die 'e' nicht etwa durch einen Leerschlag ersetzt, sondern die Zeichenkette wird bei jedem 'e' um ein Zeichen kürzer.
    nurBuchstaben(): Schreiben Sie eine Methode, die alle Zeichen, die weder Buchstaben, Ziffern noch Leerschläge sind, eliminiert. Der ausgegebene Text (Rückgabewert) enthält also insbesondere keine Sonderzeichen mehr. Aus "Hallo-oh! Welt!" wird "Hallooh Welt".
    miniKompression(): Schreiben Sie eine Methode, die im Text alle Vorkommen der Zeichenkette "en" durch 'x' ersetzt und umgekehrt ('en' → 'x' und 'x' → 'en'). Daneben sollen auch alle Vorkommen von "er" mit 'q' vertauscht werden. Zu guter Letzt soll noch jedes 'y' durch ein "ch" ersetzt werden, dafür bei jedem "ch" nur noch ein 'y' stehen. Haben Sie bemerkt worauf es hinausläuft? Wir haben soeben selbst eine kleine Kompressionsroutine geschrieben. Suchen Sie weitere reversible Ersetzungen und implementieren Sie diese.

    Das ist meine Aufgabe... die ersten beiden Punkte habe ich ziemlich schnell abgearbeitet, doch bei dem 3. Punkt bleibe ich stecken...
    Kann sein, dass ich sie falsch verstehe...



  • @codinglea Wenn du einen neuen String erzeugst (also nicht das Original änderst), kommst du mit einem Lese- und einem Schreibindex aus.

    Das Verschieben passiert da automatisch.

    @codinglea sagte in Strings Buchstaben vertauschen:

    String oder char[]-array

    Hat dein Lehrer/Tutor/... gesagt, wo er da bei C den Unterschied sieht?