Stringoperationen für Anfänger - Mögliche Hilfe ?



  • @c-beginnerw sagte in Stringoperationen für Anfänger - Mögliche Hilfe ?:

    Was macht dieses (auto &c ..) in der zweiten Zeile?

    Für jedes Element c aus in: wandle in lowercase.
    auto = Typ automatisch ermitteln (hätte hier auch char schreiben können), siehe https://en.cppreference.com/w/cpp/language/auto
    & = Referenz, d.h. keine Kopie, sondern Zeichen direkt in in ändern; siehe https://en.cppreference.com/w/cpp/language/reference

    In der vorletzten Zeile müsste auch pos-1 stehen, da der Vokal vorne im Wort stehen bleibt, richtig?

    Nein, ist richtig ohne die -1

    Die letzten 2 Zeilen ensprechen ohne rotate:
    return in.substr(pos) + in.substr(0, pos) + "i";
    Nirgends ein -1 zu sehen.

    Bei keinem Vokal wird hinten ein 'i' angehangen 🙂

    Ok, dann muss das anders. Dann überspringt man nur das rotate (siehe https://en.cppreference.com/w/cpp/algorithm/rotate), wenn pos == npos ist. Wenn man statt der string::find_first_of-Funktionen std::find_first_of verwendet, kann man sich den Check auf npos auch ganz sparen.

    Das Aufteilen des Satzes in die Bestandteile wird mit dem Befehl "strtok" ausgeführt, jedoch sollen wir diesen Befehl noch nicht verwenden. Gibt es dazu auch noch eine leichtere Lösung?

    boost::split? absl::StrSplit? Aber vermutlich sollt ihr es manuell machen und nach einem nicht-Buchstaben suchen.



  • @wob Achso, vielen Dank für die Erklärung.
    Ich habe das jetzt probiert zu Implementieren und hier ist mein Ergebnis:

    #include <iostream>
    #include <vector>
    #include <string>
    #include "keddelklopperspook.h"
    using namespace std;
     
    string extract ( string ex, const char&c ) // c legt das Trennungszeichen fest
    {
        string buff{""}; // Wörtertrennung
        for ( auto n:zeile )
        {
            if ( n != c ) //error : no match for 'operator!='
                buff+=n;
            else if (n==c && buff != "")
            {
                ex.push_back(buff);
                buff = "";
            }
        }
        if (buff != "")
            ex.push_back(buff);
        for ( unsigned int i = 0; i < zeile.at(i), i++ )
        {
            for ( auto &c : ex )
                c = tolower(c);
            size_t pos = ex.find_first_of("aeiou");
            if ( pos == string::npos )
                return ex + "i";
            rotate( begin(ex), begin(ex) + pos, end(ex));
            return ex + "i";
        }
    }
    


  • @c-beginnerw Vollständigen Code bitte.



  • Aha!

    Ich nehme an, du möchtest, daß sich jemand damit weiterbeschäftigt?
    Dann solltest du lernen, wie ein Forum funktioniert:

    • Nicht bloß Code posten und irgendwo dadrin Fehlermeldungen als Kommentar hinterlassen, sondern explizit die Fehlermeldungen (am besten per C&P) hier posten.
    • Stelle eine konkrete Frage!

    Daher nun als Gegenfragen:

    • Was ist zeile für eine Variable?
    • Möchtest du nicht eher den Parameter ex benutzen (und dir bessere Bezeichnernamen einfallen lassen)?


  • Mein uebersetzt soll den übersetzen Satz beinhalten und die Variable wort beinhaltet das einzelne Wort, welches danach in uebersetzt hineingepushed wird. Da ich den Inhalt aus dem Programm nicht kopieren kann, habe ich die Fehlermeldung nicht ausgeschrieben, jedoch steht dort jetzt :Line:21 error: no matching function for call to 'std::__cxx11::basic_string<char>::push_back(std::__cxx11::string&)'. Ich habe die Zeile 21 vorne mit einem Sternchen versehen. Meine konkrete Fragen sind nun, ob das Programm so ohne den Fehler funktionieren würde und wie man diese beheben kann.

    #include <iostream>
    #include <vector>
    #include <string>
    #include "keddelklopperspook.h"
    using namespace std;
     
    string extract ( string wort, const char&c ) // c legt das Trennungszeichen fest
    {
        string uebersetzt;
        string buff{""}; // Wörtertrennung
        for ( auto n:zeile )
        {
            if ( n != c ) 
                buff+=n;
            else if (n==c && buff != "")
            {
    *            wort.push_back(buff);
                buff = "";
            }
        }
        if (buff != "")
            wort.push_back(buff);
        for ( unsigned int i = 0; i < wort.at(i), i++ )
        {
            for ( auto &c : ex )
                c = tolower(c);
            size_t pos = wort.find_first_of("aeiou");
            if ( pos == string::npos )
                uebersetzt.push_back(wort+"i");
            rotate( begin(wort), begin(wort) + pos, end(wort));
            uebersetzt.push_back(wort+"i");
        }
    }
    


  • Die Funktion push_back gibt es nur bei einem std::vector, nicht bei einem std::string. Und es bleiben die Frage von @Th69 noch.



  • @wob sagte in Stringoperationen für Anfänger - Mögliche Hilfe ?:

    Die Funktion push_back gibt es nur bei einem std::vector, nicht bei einem std::string.

    Auch string hat push_back, aber nur für einzelne Zeichen (char). strings kann man mit append anhängen.

    https://en.cppreference.com/w/cpp/string/basic_string/append



  • @manni66 uups, tatsächlich. Ich habe push_back bei strings noch nie benutzt! Irgendwie erscheint mir bei strings += natürlicher (oder append).
    Liegt daran, dass ich bei strings eher an eine Zeichenkette als an eine Sammlung von einzelnen Buchstaben denke, vermute ich.

    (und natürlich gibt es push_back auch noch bei anderen Typen, z.B. deque)



  • @wob Ein String ist doch aber auch ein Vector oder irre ich mich da? Sonst lässt sich das wort.push_back(buff) durch ein wort.append(buff) ersetzen richtig?

    Die Gegenfragen von Th69 habe ich in dem oberen Text mit sinnvolleren Variablen geklärt



  • hunde und katzen sind auch beides säugetiere, aber ansonsten völlig verschieden. 😉



  • Solange nicht Wurstsemmel von Wurst und Supermarkt erbt ist alles in Butter ...



  • Gut, vielen Dank euch ! Das Thema kann geschlossen werden.



  • Guten Abend!

    Beim Vervollständigen des Programmes ist mir aufgefallen, dass ich noch Probleme mit den Referenzen in den Funktionen habe.

    Meine Main.cpp:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    #include "keddelklopperspook.h"
    using namespace std;
    int main()
    {
        string name;
        string zeile;// = zB"Diu pliusterst diek op ase en Pfau.";
        cout << " Datei: ";
        cin.ignore();
        getline(cin,name);
        if( !(read(name,zeile)) )
                    cout<<" Datei konnte nicht eingelesen werden";
            else{
                if(write(extract(zeile),name))
                    cout<<"Ausgabe: " +name+ "lsg.txt \n";
                else
                    cout<<"Datei konnte nicht ausgegeben werden";
        return 0;
    }
    

    Meine keddelklopperspook.cpp:

    string extract ( string& zeile , const char& c ) // Trennungszeichen
    {
        string wort = zeile;
        string uebersetzt;
        string buff{""}; // Wörtertrennung
        for ( auto n:wort )
        {
            if ( n != c )
                buff+=n;
            else if (n==c && buff != "")
            {
                wort.append(buff);
                buff = "";
            }
        }
        if (buff != ""){
            wort.append(buff);}
            for ( auto &b : wort )
                b = tolower(b);
            size_t pos = wort.find_first_of("aeiou");
            if ( pos == string::npos )
                uebersetzt.append( wort + "i" ) ;
            else
            {
                rotate( begin(wort), begin(wort) + pos, end(wort));
                uebersetzt.append( wort + "i" ) ;
            }
        return uebersetzt;
    }
    /*bool write(const string& name)
    {
        ofstream tdat( "Z:\\Programmieren 2\\Aufgabe 02\\bsp\\"+name+"lsg.txt" );
        if ( tdat.good() )
            return true;
        else
            return false;
    }
    */
    

    und die dazugrhörige Header Datei:

    #ifndef KEDDELKLOPPERSPOOK_H_INCLUDED
    #define KEDDELKLOPPERSPOOK_H_INCLUDED
    #include <vector>
    #include <string>
    using namespace std;
    bool read ( const string& name, string& zeile );
    string extract ( string& zeile, const char&c );
    void write ( const string& name );
     
    #endif // KEDDELKLOPPERSPOOK_H_INCLUDED
    

    In der keedelklopperspook.cpp stimmt irgendetwas mit der Aufteilung der Worte noch nicht, da beim ersten Wort bis zum ersten Vokal das Wort richtig abgetrennt wird, dieses jedoch ans Ende von dem gesamten String gepackt wird und die Methode mit der ersten Abtrennung auch aufhört. Habe ich in der For-Schleife einen Fehler und sind die Referenzen in den drei Methoden richtig?



  • Dann debugge doch mal diese Funktion (und schau dir dabei besonders Zeile 12 an).


Anmelden zum Antworten