Ausnahmebehandlung für eine string Funktion



  • Hallo Leute ,
    ich möchte für diese Funktion:

    string nick ("\ncapitalQ");
    

    eine Ausnahmebehandlung durchführen. Verstehe aber nicht wie das ganze genau funktioniert.
    In Skript habe ich soches Beispiel gefunden:

    int div( int z, int n ) {
    if( n == 0 ) throw std::runtime_error{ "div(), zero divisor" };
    return z/n;
    }
    int main( )
    try {
    div( 100, 0 );
    return 0;
    }
    catch( std::runtime_error& re ) {
    cerr << re.what(); // Alle StdLib Ausnahmetypen kennen eine what()
    // Operation zur Fehlermeldungs-Ausgabe.
    return -1;
    }
    

    Meine Idee war zu schauen ob die nick Funktion im Main richtig aufgerufen wird:

    #include <iostream>
    
    using namespace std;
    
    int main() {
        try{
        // Definition einer Variablen vom Typ std::string namens nick (nickname):
       string nick ("\ncapitalQ");
       cout << nick<<endl;
        }
    
    catch ( const exception& e ) {
    cerr << "Caught: " << e.what( ) << endl;
    }
    catch(...) {
    cerr << "Unbehandelter Fehler!" << endl;
        return 0;
      }
    }
    
    }
    

    was man catchen und cerren sollte . Leider keint Plan 😕



  • Hi Helenchen,

    dachte schon wir hätten Dich vergrault, und war in Sorge, das ich für meine "Gute Tat des Tages" keine Aufgabe mehr finde. 😉

    Aber mal im Ernst, irgendwie haben wir hier alle in die Wüste gepinkelt. Du wirfst uns wieder einen Knochen hin und beachtest nicht ein bisschen, von dem was z.B. SeppJ oder ich gesagt haben.
    1. Wir wissen nicht, wie überhaupt Deine komplette Aufgabenstellung ist. Ist es eine Aufgabe von Deinem Prof oder ist es eine Aufgabe, die Du Dir selbst rausgesucht hast um Deine Schwächen aufzuarbeiten.
    2. Du schreibst nur den Funktionskopf der Funktion auf die den Fehler wirft, aber nicht das Innenleben. Hast Du noch keinen und musst Dir erst noch was ausdenken, oder gibt es da eine Vorgabe wie sie aussieht? Wenn Du noch nichts hast, was soll die Funktion machen?
    3. Der Quelltext ist wieder nicht vollständig, woher sollen wir den Rest riechen.
    4. Ich habe Dir schon ein ganzes Rudel Beispiele geliefert, wie ein für Anfänger gut lesbarer Quelltext formatiert sein sollte, Aber Du klatscht uns das wieder mit der Maurerkelle einfach drauf.

    Du möchtest, dass wir Dir helfen. Machen wir auch gerne - wirklich! Aber machs uns ein bisschen leichter. Dein Zeug hinschnackeln ist auch für uns Arbeit. Wenn es Dazu hilft, Dir auf die Sprünge zu helfen, gerne jederzeit. Aber nicht, um Dir die Arbeit abzunehmen.

    Natürlich kann ich Dir jetzt irgendwas zusammen tackern und Du lädst es in Deinben Compiler und (mit einem bisschen Glück) läuft alles und Du bist zufrieden. Aber kannst Du damit wirklich zufrieden sein?
    Die Aufgabe für Dich besteht doch nicht darin, dem Prof eine Anzahl lauffähiger Programme auf den Tisch zu knallen. Dann ist es einfacher, Du kaufst Dir den großen Stroustrup und legst ihm den auf den Tisch, da wird er wenn er genug sucht schon für alle seine Fragen einen Quelltextschnipsel finden.
    Das Ziel ist doch, dass er Dich Stück für Stück dazu befähigen will, den Aufgaben entsprechend eine quelltextmäßige Lösung zu finden. Sicher sind dabei auch Sachen dabei, bei denen Du Dich fragst warum soll ich das so machen. Zum Beispiel das Wurzel ziehen einmal mit Schleifen und einmal ohne. Das ist keine Schurigelei, sondern soll dazu dienen, dass Du die beiden Möglichkeiten kennen lernst, einmal hintereinander und einmal "im Kreis rum" eine (die gleiche) Aufgabe zu lösen. Es gibt durchaus Fälle wo mal die eine mal die andere Version besser ist.
    Da Du bereits im 4. Semester bist, kann das nun nicht mehr mit Trippelschritten gehen, jetzt musst Du große Schritte machen und bei jedem einzelnen Butter bei die Fische geben.
    Wir können Dir bei jeder Aufgabe hier helfen. Aber irgendwann kommt der Tag, wo Du eine Klausur hast und wo es heist "ohne die Hilfe des Nachbern und des Forums". Dann gibt es zwei Möglichkeiten:
    Entweder Du hast alles was wir hier zusammen gemacht haben begriffen, dann wirst Du auch diese Aufgabe hinbekommen. Oder aber Du hast nur die Ergebnisse abgeschrieben und dann ist Land unter.
    Das Semester geht noch nicht allzu lange, aber ehe man sich versieht ist dann doch der Sommer ran und dann steht die Prüfung vor der Tür. Wenn man die Dinge bis dahin noch nicht begriffen hat, dann ist da in kurzer Zeit nichts mehr zu machen. Aber Informatik lebt davon die Dinge begriffen zu haben. Kochrezepte helfen meist nicht weiter. Ein bisschen hat das auch mit den unterschiedlichen Interessen von Jungs und Mädels zu tun. Mädels wollen (meist) nur dass es funktioniert. Jungs wollen wissen warum und wie es funktioniert.
    Informatik ist in dem Sinne ein "männliche Wissenschaft". Du must hier wissen wie und warum es funktioniert.

    Zu Deiner Frage bezüglich der Fehlerverarbeitung. In c ging alles nur über Rückgabecodes. z.B. -1 für Fehler. In c++ hat man als Ergänzung und Verbesserung die Fehlerbehandlung dazugenommen. Wärend ich Fehlercodes durch alle einzelnen Aufrufebenen mit durchschleppen muss, geschieht die Fehlerbehandlung nur an den dafür in Frage kommenden Stellen.

    Im Prinzip berut die Fehlerbehandlung auf drei Elementen:
    1. Einem geschützten Bereich der auf das auftreten von Fehlern vorbereitet ist. Er wird durch das Schlüsselwort try gekennzeichnet.
    2. einem Schlüsselwort, das den Fehler wirft, in dem Fall throw
    3. einem Konstrukt, das den Fehler fängt, durch das Schlüsselwort catch gekennzeichnet.

    Fehler können sowohl von den internen Bereichen des Programms geworfen werden, zum Beipiel geschieht das, wenn Du eine Zahl durch 0 teilst. Das ist matematisch nicht definiert, daher wird eine ein Fehler, also eine Exception geworfen.
    Die zweite Möglichkeit (die aus dem Beispielprogramm) ist die, dass Du selber merkst, dass das nicht zulässig ist und selber einen Fehler wirfst.
    Von der Sache her ist das gleich. Jede Exception also jeder geworfene Fehler führt zum schrittweisen Rücksprung und wenn die Exception nirgends gefangen wird bis zum Abbruch des Programms.
    Du kannst also tief drin im Programm eine Exception werfen, und das Programm kehrt zum Beispiel bis in die Main-Funktion zurück. Auf den ganzen Zwischenstationen musst Du Dich um die Weiterleitung nicht kümmern, das geht von alleine.
    Im Hauptprogramm willst Du aber den Fehler auffangen. Also richtest Du da einen geschützten Berei ein (try{}) und fängst im daran anschließendne catch-Bereich den Fehler und verarbeitest ihn.
    Durch das catch fängst Du den Fehler und entschärfst ihn, so dass er das Programm nicht weiter abbrechen kann. In dem auf catch folgenden Block machst Du dann die Fehlerbehandlung. Entweder nur eine Mitteilung, oder Du "heilst" ihn in dem Du allgemeine Standardwerte an Stelle der Falschen setzt.

    Wenn Du das erste Beispiel richtig so wie ich es Dir vorgemacht habe in Form bringst, wirst Du auch sehen, wie das funktioniert.

    Also Helenchen, lass uns erst mal die vollständige Aufgabenstellung zukommen. Damit wir wissen, was Du willst bzw. machen sollst.
    Dann entwickle erst mal eine angedachte Lösung als (auch ordentlich eingerückter) Pseudocode.
    Wenn Du den hast, kannst Du wenn genug Zeit ist den erst mal zur Disskusion hier reinstellen, und ansonsten gleich anfangen den Programmmäßig mit Fleisch zu behängen. Aber auch wieder richtig formatiert und eingerückt und alle zusammengehörigen geschweiften Klammern mit den dazugehörigen Schlüsselworten auf einer Ebene.
    Und das ganze dann posten, und uns zur Begutachtung geben. Möglichst auch mit ein wenig Kommentaren versehen, damit wir Dir folgen können, warum Du was wie gemacht hast. Dann lernst Du was und wir haben es einfacher Dir zu helfen.
    Das mit dem Pseudocode ist keine Marotte von mir, mit dem ich Dich ärgern will, sondern ergibt wirklich einen Sinn. Meine erste Diplomarbeit bestand zwischendurch nur aus einem riesigen Haufen von Zetteln mit kurzen Pseudocode-Schnipseln, und als ich die alle abgearbeitet hatte war das Programm fertig und lief wie es sollte.
    Ich hoffe, Du bist nicht enttäuscht, dass ich Deinen Quelltext nicht selber in Form gebracht habe, aber das kannst Du an Deinem Computer sicher besser als ich hier im Browserfenster des Tablets.
    Und noch einen Hinweis, nick ist keine stringvariable, sondenr eine string-Funktion!!!

    So, aber nun erst mal Schluss für heute. Schlaf gut und meld Dich wieder.

    Gruß Mümmel



  • Hi, Mümmelchen. Leider geh ich aus sehr bösen Angewohnheit davon aus das ich verstanden werde. Ich wollte nur allgemein wissen ob mein Ansatz richtig war.
    Wie du schon richtig erkannt hast, es gab davor ein Programm mit dieser Funktion:

    int main()
    {
    //Funktion vom Typ string namens nick( nickname)
    string nick("\ncapitalQ"); 
    cout << nick <<endl;
    
    return 0;
    
    }
    

    Jetzt muss laut Aufgabenstellung folgendes passieren:

    Überarbeiten Sie das Programm so, dass es mittels C++ Ausnahmen mögliche Fehler erkennt. Nach dem Abfangen eines Fehlers soll das Programm eine vernünftige Fehlermeldung ausgeben und sich beenden.

    PS: noch Mal sorry für meine Sturrheit und Unklarheiten 😉



  • Hi Helenchen,

    formatiere das Musterbeispiel aus Deinem Script ordentlich um, so wie ich es Dir gezeigt habe, auch mit einer Leerzeile zwischen der Div-Funktion und Main und dann siehst Du es alleine, dann wird es Dir (hoffentlich) wie Schuppen aus den Haaren fallen.

    In dem Beispiel ist alles wesentliche und benötigte enthalten und Du brauchst es nur noch passend zu verwenden.

    Was in Deiner Antwort immer noch fehlt ist die nick-Funktion. Wie soll sie aussehen, wie soll da eine Exception nötig werden? Wie sie geworfen wird beschreibt ja das Musterbeispiel schon passend.

    Bis denne
    Gruß Mümmel



  • muemmel schrieb:

    Hi Helenchen,

    formatiere das Musterbeispiel aus Deinem Script ordentlich um, so wie ich es Dir gezeigt habe, auch mit einer Leerzeile zwischen der Div-Funktion und Main und dann siehst Du es alleine, dann wird es Dir (hoffentlich) wie Schuppen aus den Haaren fallen.

    habe ich gerade erkannt.

    In dem Beispiel ist alles wesentliche und benötigte enthalten und Du brauchst es nur noch passend zu verwenden.

    Genau das ist mein Problem
    die if abfrage nach was in meinen Fall?
    habe nach "nicht string" versucht, aber irgendwie gefehlt mir diese Schreibweise nicht

    #include <iostream>
    #include<stdexcept>
    using namespace std;
    
     // Definition einer Variablen vom Typ std::string namens nick (nickname):
       string nick (string nickname){
       if( nickname != "") // wenn string nicht string => wie macht man es richtig ?
       throw runtime_error{ "nick(), nicht string"};
       return nickname;
       }
    int main() {
        try{
    
        nick("\ncapitalQ"); 
    
       return 0;
    
        }
    
    catch ( const runtime_error& re ) {
    
    cerr << "Caught: " << re.what( ) << endl;
    
    return -1;
    
      }
    }
    

    Wie soll sie aussehen, wie soll da eine Exception nötig werden?

    Gute Frage. Proff gibt keine genauen Hinweise darauf 😕 😞



  • Du scheinst das absolute Minimum deiner Zeit in die vernünftige wiedergabe deines Problems zu investieren, womit du es Anderen nicht gerade leicht machst dir zu helfen.

    Das richtige Formulieren eines Problems ist der erste Schritt zur Lösung. Um so früher du das begreifst, um so besser wirst du in deinem vermutlichen MINT Studium voran kommen.

    Am besten fängst du damit gleich Hier an! Versuche wie Muemmel schon sagte, deinen Quellcode (und deinen Text!) lesbar zu formatieren. Falls du nicht weißt was damit gemeint ist, google es (z.B.: "Wie formatiert man C++ Code richtig"). Anschließend versuche deine Frage mit allen nötigen Informationen zu ergänzen, angefangen mit der Aufgabenstellung vom Professor!



  • Hi Helenchen,

    normalerweise gleich erst mal 3 rechts 3 links (Ohrfeigen), weil das was Du mir da zurückgeschrieben hast immer noch nicht richtig formatiert ist.
    Wer soll es denne in Form bringen wenn nicht Du.
    Nicht String ist schon erst mal falsch, denn auch der leere String ist ein String. Es sei den, du gibst gleich NULL rüber, das wäre dann wohl wirklich kein String.
    Aber guck Dir noch mal Deinen übergebenen String an. "\ncapitalQ" ist wohl kein passender String. Wie willst Du jeweils einen NIckname eingeben, der mit \n beginnt.
    Also teste, vom ersten bis zum letzten Zeichen, ob der Wert außerhalb a-z und außerhalb A-Z liegt. (Als Sahnehäubchen kannst Du ja noch auf Umlaute und ß testen). Ists keines von all denen dann wirf ne Exception.
    Und dann ne vernünftige Fehlermeldung.
    "nick(), nicht string" ist ne Zumutung. Also (wenn Du willst)am Anfang auf NULL testen und meckern "Nickname ist NULL" und wenn beim testen der einzelnen Elemente von String "Unerlaubtes Zeichen im Nickname".

    Und korrigiere endlich Deinen Kommentar von "Definition einer Variablen vom 'Typ..."in Definition einer Function vom Typ..."

    Außerdem willst Du in Deiner Variante die Exception werfen wenn kein leerer String eingegeben wird nick != "". Du sollst sie aber werfen, wenn ein leerer String übergeben wird, also bei nick == "".

    Also drei Baustellen:
    1. prüfen ob NULL
    2. prüfen ob leerer String dazu zähle ich auch einen der nur aus Leerzeichen besteht. Also entweder trimmen oder von vorne bis hinten durchgehen ob ein Nichtleerzeichen drin vorkommt.
    3. prüfen ob unerlaubtes Zeichen im Nickname
    2 und 3 lassen sich zuusammen ermitteln, in dem Du durch den String durchläufst und dabei nicht nur testest, ob ungültiges Zeichen sopndern auch ob gültiges Zeichen vorhanden ist. Daher merkvariable vorher auf null setzen und bei gültigem Zeichen auf 1. Danach wenn keine unerlaubten Zeichen da natürlich sofort exception werfen) dann wenn >Merkvariable immer noch null ist auch ne Exception werfen ("keine gültigen Zeichen in Nick".

    und 4. bring endlich Deinen verdammten Quelltext in ne anständige Form!!! 😡

    Gruß Mümmel



  • 2 und 3 lassen sich zuusammen ermitteln, in dem Du durch den String durchläufst und dabei nicht nur testest, ob ungültiges Zeichen sopndern auch ob gültiges Zeichen vorhanden ist. Daher merkvariable vorher auf null setzen und bei gültigem Zeichen auf 1

    .

    Funktioniert nicht.Wenn ich nickname auf null setze, bekomme ich einenen Fehler:

    error: declaration of 'std::string nickname' shadows a parameter



  • Hi Helenchen,

    helenchen schrieb:

    2 und 3 lassen sich zuusammen ermitteln, in dem Du durch den String durchläufst und dabei nicht nur testest, ob ungültiges Zeichen sopndern auch ob gültiges Zeichen vorhanden ist. Daher merkvariable vorher auf null setzen und bei gültigem Zeichen auf 1

    .

    Funktioniert nicht.Wenn ich nickname auf null setze, bekomme ich einenen Fehler:

    error: declaration of 'std::string nickname' shadows a parameter

    Das war leider ein Schreibfehler von mir, da muss es 0 heißen.
    Und Du sollst ja auch in der Funktion nick nicht den Nicknamen auf Null setzen, sondern nur die Merkvariable. Nenn sie einfach GueltigVorhanden.
    Die Variable setzt Du beim erstellen in der Nick-Funktion gleich auf 0 und wenn du beim Parsen von Nickname ein gültiges Zeichen findest setzt Du GueltigVorhnden auf 1.

    Aufrufen kannst Du nick aber aus meiner sicht in Main trotzdem mit NULL

    nick( NULL );
    

    müsste zulässig sein, eventuell nach string gecastet. Aber es müsste auch ohne Cast gehen, denn NULL ist eigentlich zu allem zuweisungscompatibel.

    PS: Wo bleibt ein richtig formatierter Quelltext?

    Gruß Mümmel



  • Wie parst man einen String ( habe alles ausgegoogelt nicht gescheites)

    ⚠ Leider sieht mein Code katastrophal aus 👎 :

    #include <iostream>
    #include<stdexcept>
    using namespace std;
    
    // Definition einer Funktion vom Typ std::string namens nick (nickname):
    string nick (string nickname, string GueltigVorhanden=0){
    
       if(( nickname != GueltigVorhanden) || (nickname == GueltigVorhanden))
           throw runtime_error{ "nick(), nicht string"};
    
       else
           throw runtime_error{" nick(), string"};
    
       return nickname;
       }
    
    int main() {
    
    try{
        nick(NULL);   
    
       return 0;
    
        }
    
    catch ( const runtime_error& re ) {
    
    cerr << "Caught: " << re.what( ) << endl;
    
    return -1;
    
      }
    
    }
    

    gibt es da nicht andere Möglichkeit es zu machen ?
    😞
    PS: Je mehr ich über Exceptions lese desto schlimmer wird es 😃



  • Hinweis am Rande: installer dir mal ReSharper für C++ (mit Studentenausweis gratis) und drück CTRL+E und dann F für "Format Code" und poste erst dann Code.

    MfG SideWinder



  • Hi Helenchen,

    Eigentlich wollte ich ja nicht mehr antworten, wenn Du wieder unformatierten Müll postest, aber noch kurz nen Hinweis.

    helenchen schrieb:

    Wie parst man einen Strin1g ( habe alles ausgegoogelt nicht gescheites)
    gibt es da nicht andere Möglichkeit es zu machen ?

    kommt auf den jeweiligen Zweck an. In dem Fall ist es leicht:

    function nick
      int GueltigVorhanden = 0;
      wenn nick == NULL runtime_error{ "Nullwert übergeben"};
      Vom ersten bis zum letzten Zeichen gehen und jedes Zeichen angucken.
        wenn >= 'a' und <= 'z' oder >= 'A' und <='Z' 
            oder gleich ä oder gleich ö oder gleich ü 
            oder gleich Ä oder gleich Ö oder gleich Ü oder gleich ß 
          GueltigVorhanden = 1
        sonst
          wenn Zeichen != ' '
            throw runtime_error{ "verbotenes Zeichen"};
      wenn GueltigVorhanden == 0
        runtime_error{ "Leere Zeichenkette übergeben"};
    

    Nun musst Du nur noch ordentlichen Quelltext draus machen. Tipp von mir:ausgiebig klammern.

    PS: Je mehr ich über Exceptions lese desto schlimmer wird es 😃

    Nicht die Exceptions sind Dein Problem, sondern die Auswertung ob der String gültig ist.

    Ob er String in c++ von 1 bis n geht oder von 0 bis n-1 weiß ich nicht mehr. Der darunter liegende c_String geht auf jeden fall von 0 bis n-1 und an n liegt die /0 als Endekennzeichen. Im Notfall hätte ich den gezogen und ausgewertet. Auf dem Tablet kann ich aber auch nicht mehr als auf meinen Kopf zurückgreifen.
    Ich glaube mich aber zu erinnern, dass Du Anfang und Ende wie bei einem Vektor ermitteln konntest.
    Auch wenn Du wie SideWinder sagt ReSharper installierst solltest Du doch auch das Formatieren von Hand perfekt beherrschen. Es ist nur eine kleine Mühe und hilft beim Verstehen des Codes.

    Gruß Mümmel



  • Frage zum ReSharper , so wie ich gesehen habe gibt es dem nur für Visual Studio ich programmiere aber mit NetBeans. Klappt das nicht mit normalen Code Editor ( ich meine der das Code lesen kann wo es immer auch alles schön Aussieht 😃 )?



  • Hi Helenchen,

    einen Online-Formatierer für einen ersten Überblick findest Du hier.
    http://format.krzaq.cc/
    Du musst das Ergebnis aber noch ein wenig nacharbeiten.
    Ganz unten hast Du die Auswahl des Styles (nimm file) und den Button zum Starten.

    Gruß Mümmel



  • Hi Helenchen,

    mit dem Online-Formatierer überarbeitet sähe Dein Quelltext so aus:

    #include <iostream>
    #include <stdexcept>
    using namespace std;
    
    // Definition einer Funktion vom Typ std::string namens nick (nickname):
    string nick(string nickname, string GueltigVorhanden = 0)
    {
    
        if ((nickname != GueltigVorhanden) || (nickname == GueltigVorhanden))
            throw runtime_error{ "nick(), nicht string" };
    
        else
            throw runtime_error{ " nick(), string" };
    
        return nickname;
    }
    
    int main()
    {
    
        try
        {
            nick("capitalQ");
    
            return 0;
        }
    
        catch (const runtime_error& re)
        {
    
            cerr << "Caught: " << re.what() << endl;
    
            return -1;
        }
    }
    

    Ist schon mal nicht das verkehrteste, sauberer Allman-Stil, so wie ich ihn Dir ganz fest ans Herz legen würde.

    Und so würde ich es machen: (den Test auf NULL habe ich übrigens bei meinem Compiler nicht hinbekommen.)

    #include <iostream>
    #include <string>
    #include <stdexcept>
    
    using namespace std;
    
    // Definition einer Funktion vom Typ std::string namens nick (nickname):
    string nick(string nickname )
    {
      if ( nickname.empty() )                      // wenn leere Zeichenkette
        throw runtime_error( "NickName ist leer" );
    
      int GueltigVorhanden = 0;                    // Vorbelegen auf Falsch
      for ( std::string::iterator it=nickname.begin(); it!=nickname.end(); ++it)   // durch alle Zeichen gehen
      {
        if ( ( *it >= 33 ) && ( *it <= 126 ) )     // wenn erlaubtes ASCII-Zeichen ich hab hier mal
                                                   // auf alle druckbaren Zeichen erweitert (Test einfacher)
        {
          GueltigVorhanden = 1;                    // nicht nur Leerzeichen
        }
        else                                       // sonst wenn kein erlaubtes
        {
          if ( *it != ' ' )                        // und wenn es kein Leerzeichen ist
          {
            throw runtime_error( "Unzulässiges Zeichen" );  // muss es ein falsches sein, also Exception werfen
          }
        }
      }
      if ( GueltigVorhanden == 0 )
        throw runtime_error( "NickName enthält nur Leerzeichenn" );
      return nickname;
    }
    
    int main(int argc, _TCHAR* argv[])
    {
        string x;
        string Nick_Name;
      try
      {
        Nick_Name = nick( "\ncapitalQ" );
        cout << "Gültiger NickName eingegeben" << endl;
                                     // Eingabe damit Ergebnis sthen bleibt
        cout << "Eingabe für weiter" << endl;
        cin >> x;
    
        return 0;
      }
      catch (const runtime_error& re)
      {
        cerr << "Error: " << re.what() << endl;
        cout << "Eingabe für weiter" << endl;
        cin >> x;
        return -1;
      }
    }
    

    Gruß Mümmel



  • hier ist mein Code leider immer noch fehlerhaft

    #include <iostream>
    #include <stdexcept>
    #include <string>
    using namespace std;
    
    // Definition einer Funktion vom Typ std::string namens nick (nickname):
    string nick(string nickname)
    {
    
        int GueltigVorhanden = 0;
    
        if (nick == NULL)
            throw runtime_error{ " nick(), Nullwert übergeben " };
    
        for (size_t i = 0; i < nickname.size(); ++i)
            ;
        if (((nickname >= 'a' && nickname <= 'z' || nickname >= 'A' && nickname <= 'Z')
                || (nickname == 'ae' || nickname == 'oe' || nickname == 'ue'))
            || (nickname == 'AE' || nickname == 'OE' || nickname == 'UE' || nickname == 'SS'))
    
            GueltigVorhanden = 1;
    
        else if (nick != '')
            throw runtime_error{ " nick(), verbotenes Zeichen" };
        if (GueltigVorhanden == 0)
            throw runtime_error{ " nick(), Leere Zeichenkette übergeben" };
    }
    
    int main()
    {
    
        try {
    
            nick(NULL);
    
            return 0;
        }
    
        catch (const runtime_error& re) {
    
            cerr << "Caught: " << re.what() << endl;
    
            return -1;
        }
    }
    

    was meintest du hier Mümmelchen?

    wenn >= 'a' und <= 'z' oder >= 'A' und <='Z'
    oder gleich ä oder gleich ö oder gleich ü
    oder gleich Ä oder gleich Ö oder gleich Ü oder gleich ß

    und

    wenn Zeichen != ' '

    das sind die meist Fehlerhaften Zeilen bei mir . Habe ich da mal wieder was falsch verstanden? 🙄



  • Hi Helenchen,

    Zeichen != '' geht nicht, da muss zumindest ein Leerzeichen rein.
    Und den Rest solltest Du vernünftig ergänzen. Ich hab Dir nur hingeschrieben, was Du für Tests machen sollst.
    Ich hab Deine Fehler mal auskommentiert und etwas kommentiert. Bitte alles lesen.

    string nick(string nickname)
    {
    
        int GueltigVorhanden = 0;                         // soweit OK
    
    //    if (nick == NULL)                                          // hab ich nicht zum laufen bekommen
    //        throw runtime_error{ " nick(), Nullwert übergeben " }; // mein Compiler weigerte sich, mit NULL zu vergleichen
    
    //    for (size_t i = 0; i < nickname.size(); ++i) // nimm für Strings besser die Variante, die ich aufgeschrieben habe, 
                                                       // müsste aber auch so gehen.
    
            ;                                          // mit dem Semikolon als Schleifenkörper beendest Du die Schleife 
                                                       // ohne was zu tun.
    
    // Du vergleichst hier wirklich nen String mit nem einzelnen Zeichen???
    
    //    if (((nickname >= 'a' && nickname <= 'z' || nickname >= 'A' && nickname <= 'Z')
    //            || (nickname == 'ae' || nickname == 'oe' || nickname == 'ue'))             
    //        || (nickname == 'AE' || nickname == 'OE' || nickname == 'UE' || nickname == 'SS'))
    
    // ich hatte nicht umsonst geschrieben "Tip von mir: ausgiebig klammern"
    
    // ich würde mich nicht darauf verlassen, dass der Compiler 'ae' als 'ä' interpretiert
    
    // mache es besser so
        for (size_t i = 0; i < nickname.size(); ++i)
        {
            if (
                 ( ( nickname[ i ] >= 'a' ) && ( nickname[ i ] <= 'z' ) ) ||
                 ( ( nickname[ i ] >= 'A' ) && ( nickname[ i ] <= 'Z' ) ) ||
                 ( nickname[ i ] == 'ä' ) ||
                 ( nickname[ i ] == 'ö' ) ||
                 ( nickname[ i ] == 'ü' ) ||
                 ( nickname[ i ] == 'Ä' ) ||
                 ( nickname[ i ] == 'Ö' ) ||
                 ( nickname[ i ] == 'Ü' ) ||
                 ( nickname[ i ] == 'ß')
               )                               // mit Zeiger statt Indexzugriff wäre es performanter
                                               // geht aber auch so
            {
                GueltigVorhanden = 1;
            }
            else
            {
              if ( nickname[ i ] != ' ' )
              {
                throw runtime_error( " nick(), verbotenes Zeichen" );
              }
            }
        }
        if (GueltigVorhanden == 0)
        {
            throw runtime_error( " nick(), Leere Zeichenkette übergeben" );
        }
    }
    
    int main(int argc, _TCHAR* argv[])
    {
        string x;
    
        try {
    
            nick("/nOma");
    
            return 0;
        }
    
        catch (const runtime_error& re) {
    
            cerr << "Caught: " << re.what() << endl;
    
        cout << "Eingabe für weiter" << endl;
        cin >> x;
            return -1;
        }
        cout << "Eingabe für weiter" << endl;
        cin >> x;
    }
    

    Gruß Mümmel



  • leider meckert compiler auf die umlaute => multi - character char:

    #include <iostream>
    #include <stdexcept>
    #include <string>
    
    using namespace std;
    
    // Definition einer Funktion vom Typ std::string namens nick (nickname):
    string nick(string nickname)
    {
        if (nickname.empty()) // wenn leere Zeichenkette
            throw runtime_error("NickName ist leer");
    
        int GueltigVorhanden = 0; // Vorbelegen auf Falsch
        for (size_t i = 0; i < nickname.size(); ++i) // durch alle Zeichen gehen
        {
            if (
                   ((nickname[i] >= 'a') && (nickname[i] <= 'z'))
                || ((nickname[i] >= 'A') && (nickname[i] <= 'Z'))
                || (nickname[i] == 'ä')
                || (nickname[i] == 'ö')
                || (nickname[i] == 'ü')
                || (nickname[i] == 'Ä')
                || (nickname[i] == 'Ö')
                || (nickname[i] == 'Ü')
                || (nickname[i] == 'ß')
               )
            {
                GueltigVorhanden = 1; // nicht nur Leerzeichen
            }
            else // sonst wenn kein erlaubtes
            {
                if (nickname[i] != ' ') // und wenn es kein Leerzeichen ist
                {
                    throw runtime_error(
                        " nick(), verbotenes Zeichen "); // muss es ein falsches sein,
                    // also Exception werfen
                }
            }
        }
    
        if (GueltigVorhanden == 0) {
            throw runtime_error{ " nick(), Leere Zeichenkette übergeben" };
        }
    }
    
    int main()
    {
        string x;
    
        try {
            nick(" /ncapitalQ ");
    
            return 0;
        }
    
        catch (const runtime_error& re) {
            cerr << " Caught: " << re.what() << endl;
    
            cout << " Eingabe für weiter " << endl;
            cin >> x;
    
            return -1;
        }
        cout << " Eingabe für weiter " << endl;
        cin >> x;
    }
    

    habe versucht es durch setlocal zu beheben keine Chance 👎



  • Hi Helenchen,

    lass entweder die Umlaute weg, dann können im Nickname eben keine Umlaute verwendet werden, oder verwende den Numerischen Wert der Umlaute.
    Dabei musst Du dann aber ein wenig casten für den Vergleich.
    Entweder
    ( (int) nickname[i] == 196 ) // 196 = Ä, zumindest in Codeseite (Win-1252)
    oder
    ( nickname[i] == (char) 196 )
    Ich würde die zweite Form schöner finden, weil es ja auf einen char-Vergleich ankommt.
    Probiere notfalls aus, was die Umlaute bei Dir für einen Wert haben.
    Lies dazu ÄÖÜäöüß von der Konsoleneingabe (cin) ein und gib die einzelnen Zahlenwerte von den 7 Zeichen nach cout aus.
    etwa so

    string x;
    cout << "Gib die Umlautreihe ein" << endl;
    cin >> x;
    cout << (int) x[0] << '|' <<(int) x[1] << '|' << (int) x[2[e]cap[/e]] 
    << '|' << (int) x[3] << '|' << (int) x[4] << '|' << (int) x[5] << '|' << (int) x[6] << '|' <<  endl;
    

    Viel Erfolg, viel Spaß und eine gute Nacht wünscht Mümmel.

    PS: Gefährliche Falle, habs eben noch schnell korrigiert. Sieben Zeichen gehen ja von 0 nur bis 6 und nicht bis 7.

    Gruß Mümmel



  • muemmel schrieb:

    den Test auf NULL

    Wenn dann würde ich eh auf nullptr testen. Und verwirr bitte die Anfänger nicht mit _TCHAR und ähnlichem.


Log in to reply