std::string toupper



  • Wird dann ein ü nicht zu einem Ü?

    Und ich benutze TCHAR (also ein typedef für entweder char oder wchar_t). Muss ich da irgendwas beachten?



  • dumme frage

    Keinesfalls.

    warum reicht

    transform(s.begin(), s.end(), s.begin(), toupper);

    nicht?

    toupper erwartet und liefert int. Allerdings muss das Argument (sofern es sich nicht um EOF handelt) als unsigned char darstellbar sein.

    Nun enthält s als Elemente chars. Da chars in C++ sowohl signed als auch unsigned sein können (implementation-defined) müssen wir explizit sicherstellen, dass sich diese chars als unsigned chars repräsentieren lassen.
    Dies erreicht man durch den cast. Für Systeme wo char = unsigned char ist, ist der cast eine noop (und unnötig). Ansonsten ist er aber erfoderlich.



  • Wird dann ein ü nicht zu einem Ü?

    Das kommt in meinem Beispiel auf das globale C-Locale des Systems an. Im Standardfall bleibt 'ü' ein 'ü', da 'ü' kein Buchstabe des englischen Alphabets ist (toupper 'ü' also ignoriert).

    Und ich benutze TCHAR (also ein typedef für entweder char oder wchar_t). Muss ich da irgendwas beachten?

    Yep. Für den Fall das TCHAR = wchar_t musst du towupper aufrufen.

    [ Dieser Beitrag wurde am 23.05.2003 um 19:34 Uhr von HumeSikkins editiert. ]



  • Original erstellt von HumeSikkins:
    **
    toupper erwartet und liefert int. Allerdings muss das Argument (sofern es sich nicht um EOF handelt) als unsigned char darstellbar sein.**

    wieso geht dann:

    char c = 'a', d;
    d = tolower(c);
    

    ? (oder geht das am ende gar nich?)



  • wieso geht dann:

    char c = 'a', d;
    d = tolower(c);

    Auf was bezieht sich deine Frage?
    Warum sich das übersetzen lässt sollte klar sein. char wird nach int promoted und von int nach char gibt's ne Standardkonvertierung.

    Das dabei aber das gewünschte Ergebnis rauskommt ist *nicht* garantiert.
    Das ist so ein Design-by-contract-Ding. Es gibt einen Vertrag zwischen tolower/toupper um dem Aufrufer. tolower/toupper *garantieren* ein bestimmtes Verhalten unter bestimmten Voraussetzungen (die der Aufrufer erfüllen muss). Wenn du diese Vorausetzungen nicht erfüllst, verfallen alle garantien.
    Es kann immer noch das rauskommen was du erwartest. Es gibt aber keine Garantie mehr. Kommt nicht das raus, was du erwartest hast du kein Recht dich zu beschweren.

    Das ganze nennt man dann "Programming by coincidence". Und selbiges ist in der Regel keine gute Idee.



  • Original erstellt von HumeSikkins:
    **[quote] wieso geht dann:
    Das dabei aber das gewünschte Ergebnis rauskommt ist *nicht* garantiert.
    Das ist so ein Design-by-contract-Ding. Es gibt einen Vertrag zwischen tolower/toupper um dem Aufrufer. tolower/toupper *garantieren* ein bestimmtes Verhalten unter bestimmten Voraussetzungen (die der Aufrufer erfüllen muss). Wenn du diese Vorausetzungen nicht erfüllst, verfallen alle garantien.
    Es kann immer noch das rauskommen was du erwartest. Es gibt aber keine Garantie mehr. Kommt nicht das raus, was du erwartest hast du kein Recht dich zu beschweren.

    Das ganze nennt man dann "Programming by coincidence". Und selbiges ist in der Regel keine gute Idee.**

    Laber mich bitte nich mit Modeworten voll, sondern sag mir einfach, dass mein Schnippsel UB is. 🙂



  • Original erstellt von HumeSikkins:
    [char c = 'a', d;
    d = tolower(c);
    ]
    [...]
    Das dabei aber das gewünschte Ergebnis rauskommt ist *nicht* garantiert.

    Es ist (ich habe den C++-Vers gerade _nicht_ gefunden) garantiert, dass alle im Basic-Executionset enthaltenen Zeichen einen positiven Wert haben, unabhängig von der Repräsentation von 'char'. Damit ist das Ergebnis hier wohldefiniert, denke ich.



  • @Daniel E.
    Ich habe meine Informationen aus "Effective STL" von Scott Meyers und von dir persönlich (du hast schon mehrfach auf falsche Verwendung von tolower/toupper hingewiesen). Kann also auch alles falsch sein. Und gerade weil ich mir nicht 100% sicher war, habe ich eben auch nicht geschrieben, dass es sich hier um *undfiniertes* Verhalten handelt.

    Es ist (ich habe den C++-Vers gerade _nicht_ gefunden) garantiert, dass alle im Basic-Executionset enthaltenen Zeichen einen positiven Wert haben, unabhängig von der Repräsentation von 'char'. Damit ist das Ergebnis hier wohldefiniert, denke ich.

    Ich verstehe deinen Satz nicht.
    Das nachfolgende Programm liefert auf dem VC 6.0 eine Ausgabe von -4. Und wenn ich Scott Meyers richtig verstanden habe, muss ich genau in einer solchen Situation c *vor* dem Aufruf von tolower nach unsigned char casten.

    // hier noch Header usw.
    int main()
    {
        char c = 'ü';
        cout << (int) c << endl;
    }
    

    @Mr. N
    Überleg dir mal bitte wie du mit mir redest. Ich bin weder dein Kneipenkumpel, noch kenne ich deinen Humor. Wenn du der Meinung bist, dass ich dich mit Modeworten voll labere, dann kann man das sicher auch freundlicher sagen.
    Ich habe schließlich nur *versucht* deine Frage zu beantworten.



  • Original erstellt von HumeSikkins:
    Das nachfolgende Programm liefert auf dem VC 6.0 eine Ausgabe von -4. Und wenn ich Scott Meyers richtig verstanden habe, muss ich genau in einer solchen Situation c *vor* dem Aufruf von tolower nach unsigned char casten.

    Jup, sehe ich genauso. 'ü' ist nicht im 'basic execution character set' enthalten, es muss also nicht im Positiven liegen. Bei 'a' liegt IMHO ein Spezialfall vor:
    'a' ist im BECS, damit ist es garantiert positiv und kann in einem 'signed char' und in einem 'unsigned char' abgespeichert werden, wobei beide den gleichen Wert enthalten. Nehmen wir an, wir speichern 'a' in einem 'signed char' (bei 'unsigned char' ist die Sache sowieso klar). Der enthält den Wert, den 'a' repräsentiert, der dann, beim Funktionsaufruf von 'toupper', in einen 'int' verwandelt wird. Dieser 'int' liegt zweifelsohne im Positiven.

    Die toupper-ohne-cast-Methode funktioniert also für einen Spezialfall, Zeichen aus dem BECS, die mit Cast immer (außer man castet 'EOF' ;)) und sollte darum benutzt werden. Wenn ich mich nicht täusche und ich mich klar ausgedrückt habe, versteht sich...

    [ Dieser Beitrag wurde am 24.05.2003 um 12:00 Uhr von Daniel E. editiert. ]



  • @Daniel E.
    Danke. Jetzt habe ich es verstanden. Ich hatte wohl das kleine Wörtchen 'hier' überlesen und dann deine Aussage falsch interpretiert.


Anmelden zum Antworten