Strings mit compare vergleichen und exeption werfen



  • Hallo zusammen,

    ich habe eine Klasse "Kunde" geschrieben, in der der "Absender" und der "Empfänger" als String angelegt sind.
    Nun wollte ich eine Überprüfung (vergleich) anstellen um gegebenenfalls eine Exeption der Klasse "FehlSendung" zu werfen.

    #include <string>
    
    void checkSendung (Kunde &vs) {
    FehlSendung f;
    if (0== Absender.compare(Empfänger) throw f;   //throw FehlSendung 
    
    }
    

    Nun hätte ich zwei Fragen:
    1. Ist es besser strcmp zu benutzen oder compare? da beides in meinem Buch(leider etwas älter) steht.

    2. Könnte ich anstat f nicht gleich "throw FehlSendung" schreiben. Bei mir kommt da immer eine Fehlermeldung, habe dies nun aber schon ein par mal in der Variante gesehen.

    Eventuell kann mit jm. helfen Danke und Grüße



  • if(absender != empfaenger) throw FehlSendung();



  • Wenn "Empfänger" und "Absender" vom Typ std::string sind, solltest du compare benutzen. strcmp ist ein Überbleibsel aus C und erwartet als Arugmente Zeichenketten vom Typ const char*, die mit 0 terminiert sind (was std::string nicht garantiert). Daher muss man den Code ein wenig umschreiben:

    std::string a,b;
    if( std::strcmp(a.c_str(), b.c_str()) == 0) // könnte Overhead produzieren, falls std::string intern nicht nullterminiert ist
     ...
    

    compare ist eine Funktion von std::string und daher muss man nichts ändern:

    if(a.compare(b) == 0)
    

    Von der Perfomance sollte beides gleich sein, außer dass compare die Länge beider strings kennt und daher schon früher abbrechen kann.

    Zur 2. Frage:
    throw erwartet, dass du ein Objekt wirfst und keinen Typen.



  • Wenn es nur um Gleichheit geht, kannst du natürlich auch direkt den Gleich-Operator benutzen

    if(a==b) ...
    

  • Mod

    Wenn "Empfänger" und "Absender" vom Typ std::string sind, solltest du compare benutzen.

    Nein. compare für zwei string s ist hier definitiv überflüssig. == passt besser.

    strcmp ist ein Überbleibsel aus C und erwartet als Arugmente Zeichenketten vom Typ const char*, die mit 0 terminiert sind (was std::string nicht garantiert).

    std::string garantiert dass der String auf den c_str() zeigt nullterminiert ist (sonst wär's ja auch kein String). Das reicht.

    könnte Overhead produzieren, falls std::string intern nicht nullterminiert ist

    🙄



  • Arcoth schrieb:

    strcmp ist ein Überbleibsel aus C und erwartet als Arugmente Zeichenketten vom Typ const char*, die mit 0 terminiert sind (was std::string nicht garantiert).

    std::string garantiert dass der String auf den c_str() zeigt nullterminiert ist (sonst wär's ja auch kein String). Das reicht.

    ja std::string hat den end pointer auf einem \0 liegen soviel ich weiß.

    d.h. wenn man string.c_str() benutzt, geht die klasse hin und übergibt nur den char ponter vom anfang, der rest ist ja dann durch den nullterminator geregelt 😉

    sollte also keine krassen performanceverluste geben wenn man c_str() benutzt


  • Mod

    Und wenn der string Nullzeichen enthält?



  • SeppJ schrieb:

    Und wenn der string Nullzeichen enthält?

    Dann ist std::string die falsche Klasse. (Selbst wenn std::string das theoretisch unterstüzt ist das einfach semantisch falsch.)


  • Mod

    monolith schrieb:

    SeppJ schrieb:

    Und wenn der string Nullzeichen enthält?

    Dann ist std::string die falsche Klasse. (Selbst wenn std::string das theoretisch unterstüzt ist das einfach semantisch falsch.)

    Wieso? Die Festlegung, dass eine Zeichenkette sematisch keine Nullen enthalten sollte ist doch bloß eine aus der Not geborene Krücke in C. Aus den mangelnden technischen Möglichkeiten der Umsetzung in einer Sprache auf die Grundlegende Semantik einer Datenstruktur zu schließen ist falsch. Sonst könnte ein Pascaler auch argumentieren, dass Zeicheketten mit mehr als 255 Zeichen semantisch falsch wären oder so ziemlich jeder Programmierer, dass es keine Ganzzahlen größer als 2^32-1 gäbe.
    Beispiel: Irgendwelche Steuersequenzen sind semantisch immer noch Zeichenketten und könnten Nullzeichen enthalten*.

    *: In der Praxis wird das natürlich selten der Fall sein, weil man damit rechnen muss, dass die Sequenz irgendwann zwischendurch mal durch eine in C geschriebene Software verarbeitet wird, die dann nicht korrekt funktionieren würde.



  • SeppJ schrieb:

    Und wenn der string Nullzeichen enthält?

    dann nimm ein std::vector<char> und mach ne memcmp drauf... 😉



  • SeppJ schrieb:

    Beispiel: Irgendwelche Steuersequenzen sind semantisch immer noch Zeichenketten und könnten Nullzeichen enthalten*.

    *: In der Praxis wird das natürlich selten der Fall sein, weil man damit rechnen muss, dass die Sequenz irgendwann zwischendurch mal durch eine in C geschriebene Software verarbeitet wird, die dann nicht korrekt funktionieren würde.

    Nö, auch in C kann man

    char *ptr;
    

    bzw.

    char byte[1000];
    

    verarbeiten, ohne Funktionen zu bemühen, die sich darauf verlassen, dass der relevante Teil mit 0 endet. Die entsprechende Information (wo ist Ende) muss dann halt anders übermittelt werden/vereinbart sein.
    Es ist ja nicht zwangsweise so, dass hinter so einer Datenstruktur immer ein C-String (im Sinne von nullterminierte Bytefolge) steckt.


  • Mod

    Natürlich kann C das. Aber willst du dich da drauf verlassen, dass das jeder auf der Welt richtig macht?


Anmelden zum Antworten