String rückwärts ausgeben



  • @marktheshark

    Deine Lösung geht ein wenig an der Aufgabenstellung vorbei, denke ich. Die Aufgabenstellung war doch bestimmt, einen string umzudrehen und den dann auszugeben. Du gibst einfach nur den string rückwärts aus, was unterm Strich das Gleiche, aber unflexibel ist.
    Angenommen, du möchtest den umgedrehten string intern für iwas benutzen, dann müsstest du das an der Stelle wieder machen. Hättest du eine Funktion, die das für dich erledigt, könntest du einfach wieder die Funktion aufrufen und mit deren Ergebnis weitermachen. Du möchtest als Entwickler eigentlich immer wiederverwendbare Funktionen schreiben, um das Rad nicht x-mal neu zu erfinden.



  • @marktheshark
    Also String-Funktion zum Umdrehen kenne ich keine. Aber es gibt eine allgemeine Funktion in der Standard-Library die du verwenden kannst: https://en.cppreference.com/w/cpp/algorithm/reverse
    Die funktioniert auch mit Strings.



  • @wob Alles klar vielen Dank. Was ist an einer for schleife besser als an einer while? und wie kann ich einen neuen string einspeichern statt ihn einfach auszugeben?

    einfach statt

    cout << ...
    
    string zwei;
    
    ...
    
    zwei = ...
    

    ?



  • @marktheshark sagte in String rückwärts ausgeben:

    Was ist an einer for schleife besser als an einer while?

    In der for Schleife kannst du direkt die Variable i definieren. Ausserhalb der Schleife wird die nicht benötigt, daher wäre es besser wenn sie ausserhalb der Schleife auch gar nicht existiert. Mit der for Schleife bekommst du das "gratis". Ebenso gibt es im for Schleifenkopf einen Platz für das i++.

    Ansonsten spielt da auch viel Konvention mit. Es ist einfach üblich Schleifen dieser Art mit for zu schreiben. Und wenn ein Programm ohne ersichtlichen Grund mit solchen Konventionen bricht, dann ist das immer etwas verwirrend.

    und wie kann ich einen neuen string einspeichern statt ihn einfach auszugeben?

    Es gibt z.B. die Funktionen push_back mit der du ein Zeichen hinten an einen String anhängen kannst. Damit kannst du einen String quasi Zeichen für Zeichen aufbauen.



  • @hustbaer Alles klar vielen Dank,

    mein code sieht bis jetzt so aus:

    #include <iostream>
    #include <string>
    using namespace std;
    
    string wort(string neu){
        string zwei;
        int i = 0;
        while (i <= (neu.length()-1))
        {
            cout << neu.at((neu.length()-(i+1)));
            i++;
        }
        return zwei;
          
    }
    
    int main(){
        string result;
        string input;
        cout << "Geben Sie einen Satz ein: " << endl;
        cin >> input;
        result = wort(input);
        cout << result << endl;
        
        return 0;
    
    
    }
    

    Ich habe das mit der for Schleife noch nicht gemacht, wichtiger ist mir Zeile 10.

    Wie kann ich das Ergebnis dieser schleife in den string zwei, den ich in Zeile 6 definiert habe, einspeichern? Ich möchte ja auf das out in Zeile 10 verzichten,

    aber

    {
    zwei = neu.at((neu.length()-(i+1)));
    ...
    }
    

    funktioniert ja nicht.

    Könntest du mir da weiterhelfen?

    LG



  • @marktheshark sagte in String rückwärts ausgeben:

    @hustbaer Alles klar vielen Dank,

    mein code sieht bis jetzt so aus:

    while (i <= (neu.length()-1))
    {
       // cout << neu.at((neu.length()-(i+1)));
         zwei.push_back (neu.at((neu.length()-(i+1))));
        i++;
    }
    

    Aber die Indexberechnung sieht doch sehr unübersichtlich aus, warum nicht:

        int i = neu.length() - 1;
        while (i >= 0)
        {
            zwei.push_back (neu[i]);
            i--;
        }
    


  • @marktheshark sagte in String rückwärts ausgeben:

    Wie kann ich das Ergebnis dieser schleife in den string zwei, den ich in Zeile 6 definiert habe, einspeichern? Ich möchte ja auf das out in Zeile 10 verzichten,

    Du musst das Zeichen, das du ausgeben willst, an den string "zwei" (ein schlechter Name*) dranhängen.

    Du kannst dazu push_back verwenden, wie von @hustbaer vorgeschlagen, oder einfach += schreiben.
    Also zum Beispiel gibt folgender Code "Hi" aus:

    string zwei;
    zwei += 'H';
    zwei += 'i';
    cout << zwei << '\n';
    

    * zum Namen: benenne die Variablen (und auch Funktionen) nach dem, was diese semantisch enthalten sollen. Deine Funktion sollte nicht wort heißen: das würde nämlich vermuten lassen, dass sie einfach irgendwie ein Wort zurückgibt. Konkret soll sie das aber umgekehrt zurückgeben, also wäre ein Name wie "von_hinten_nach_vorn" oder "rueckwaerts" besser (oder noch besser: Englisch nutzen und die Funktion "reverse" oder ähnlich nennen). Ich reite darauf rum, weil gute Namen wichtig sind, aber nicht immer ganz leicht zu finden sind. Sie sollten möglichst eindeutig beschreiben, was sie tun, aber auch nicht "unhandlich" lang sein. Die übergebene Variable sollte nicht "neu" heißen, denn das ist logisch gesehen ja der "alte" String. Du könntest die "input" nennen oder "original" (gut, auch nicht kreativ); und "zwei" könntest du zum Beispiel "result" nennen. Vielleicht findest du bessere Namen, aber nutze jedenfalls nicht "zwei", "wort" und "neu" hier. Wobei: "neu" würde vielleicht noch an die Stelle von "zwei" passen. Nimm lieber englisch, aber da ist "new" schon anderweitig vergeben. Fällt also raus.



  • @Belli sagte in String rückwärts ausgeben:

    Aber die Indexberechnung sieht doch sehr unübersichtlich aus, warum nicht:
    int i = neu.length() - 1;
    while (i >= 0)

    ARGH! Nein! Sowas will man nicht. Das length() liefert einen size_t, ist also unsigned. Wenn der String 0 lang ist, steht rechts vom Gleichzeichen mit size_t(0) - 1 eine sehr große Zahl. Jetzt muss ich anfangen mir Gedanken zu machen, was bei der Konvertierung nach int passiert, ob diese überhaupt definiert ist. Aber völlig unabhängig davon, was da im Standard definiert ist, WILL ich da KEINEN Gedanken dran verschwenden. Wenn ich es gar nicht erst zu sowas kommen lasse, kann ich auch keinen Fehler mit signed/unsigned machen. Außerdem generiert der Code möglicherweise eine Compilerwarnung wegen signed/unsigned und dann "fixt" das jemand durch Ersetzen von int i durch size_t i oder auto i - und boom!

    Also lieber die Standard-Vorwärtsloop ohne sich Gedanken machen zu müssen verwenden oder hier, wo man rückwärts loopen will, Folgendes machen:

    auto i = original.length();
    while (i--) {
        result += original[i];
    }
    

    (zu den Variablennamen schrieb ich ja schon was, habe hier jetzt "neu" durch "original" und "zwei" durch "result" ersetzt)



  • String Funktionen sind auch die Kopierkonstruktoren, die man auch mit Iteratoren nutzen darf. Von Reverse Iteratoren war bereits die Rede, so dass man mit diesem Wissen eine Lösung schreiben kann, die ganz ohne Schleife auskommt.



  • @john-0 sagte in String rückwärts ausgeben:

    String Funktionen sind auch die Kopierkonstruktoren, die man auch mit Iteratoren nutzen darf. Von Reverse Iteratoren war bereits die Rede, so dass man mit diesem Wissen eine Lösung schreiben kann, die ganz ohne Schleife auskommt.

    Ja, dies wäre die C++-ige Lösung: string s="Hallo"; string reversed(s.rbegin(), s.rend());
    Aber ich vermute mal, dass dies eine Übungsaufgabe ist, wo Schleifen geübt werden sollen.

    @marktheshark Siehe Konstruktor Nummer 6 hier: https://en.cppreference.com/w/cpp/string/basic_string/basic_string



  • @wob sagte in String rückwärts ausgeben:

    Aber ich vermute mal, dass dies eine Übungsaufgabe ist, wo Schleifen geübt werden sollen.

    Wahrscheinlich ist das so, aber dann sollte man das auch in die Aufgabenstellung hineinschreiben.



  • @john-0

    Dann müsste der Aufgabensteller aber auch wissen, dass es sowas gibt. Und bei der Qualität der gestellten Fragen und der übrigen Aufgaben, die hier so im Forum auftauchen, ist das oft nicht der Fall.


Anmelden zum Antworten