Frage zu tolower aus ctype



  • Hallo,

    In diesem Thread
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-139836.html ist unter anderem eine Umwandlung Gross/Kleinbuchstaben mittels tolower und transform erläutert. Mal abgesehen von der signed/unsigned-Problematik funktionierte das bei mir auch nicht, weil tolower nicht eindeutig war. Ich habe jetzt hier folgendes gefunden (angepasst).

    locale loc;
    string tempobject;
    // tempobject wird gefüllt
    // und jetzt transformiert
    use_facet<ctype<string::value_type> >(loc).tolower(tempobject.begin(), tempobject.end());
    

    Existiert hier die signed/unsigned-Problematik noch?
    Bei den bisherigen Tests hat es funktioniert. Ich habe allerdings auch noch nicht alle möglichen chars getestet.

    Vielen Dank im Voraus.



  • Was meinst du mit "nicht eindeutig"?

    Wie dein Code mit dem signed/unsigned-Problem umgehen kann, hängt afaik stark von der Implementierung ab. Ich würde mich nicht darauf verlassen. (wenn du es testen willst - verwende Zeichen jenseits von '\x8F', darunter ist es sowieso nicht relevant)

    Aber die Locale-Version hat auf jeden Fall einen Vorteil gegenüber der C-Funktionen: Du kannst dort auch andere Locales verwenden (soweit vorhanden, z.B. Deutsch - wandelt auch Umlaute um).

    (PS: Übrigens gibt es von tolower() auch eine Zwei-Parameter-Version, die zu deinem Code äquivalent ist)



  • Hallo,

    Mit nicht eindeutig, meine ich folgendes

    transform (tempobject.begin(),tempobject.end(), tempobject.begin(), static_cast<int (*)(int)>(tolower));
    

    Wenn ich das so versuche anzuwenden, kommt folgende Fehlermeldung.
    "Überladene Funktion 'tolower' ist in diesem Kontext mehrdeutig"

    Die obige Variante hat das Problem nicht. Wenn ich eine der anderen tolower in einer Schleife verwende geht es auch.
    Diese tolower

    template <class charT> 
    charT tolower (charT c, const locale& loc) const;
    

    ist auch nicht völlig äquivalent zur der aus meinem Code. Zumindest kann ich da auf das transform verzichten.



  • Braunstein schrieb:

    Hallo,

    Mit nicht eindeutig, meine ich folgendes

    transform (tempobject.begin(),tempobject.end(), tempobject.begin(), static_cast<int (*)(int)>(tolower));
    

    Wenn ich das so versuche anzuwenden, kommt folgende Fehlermeldung.
    "Überladene Funktion 'tolower' ist in diesem Kontext mehrdeutig"

    Das ist das Problem mit überladenen Funktionen und Funktionszeigern. Eventuell könnten die Funktor-Wrapper der STL (ptr_fun) da weiterhelfen.
    (ohne Garantie)

    template <class charT> 
    charT tolower (charT c, const locale& loc) const;
    

    ist auch nicht völlig äquivalent zur der aus meinem Code. Zumindest kann ich da auf das transform verzichten.

    Ups, da dürftest du recht haben (hab' wohl nicht aufmerksam genug gelesen.

    PS: Eine andere Lösung wäre es, eine eindeutige Hilfsfunktion um tolower herumzuschreiben - damit kannst du auch das Vorzeichen-Problem umgehen:

    inline unsigned char my_tolower(unsigned char v)
    { return tolower(v); }
    
    ...
    transform(s.begin(),s.end(),s.begin(),my_tolower);
    


  • Danke erstmal,

    Das mit ptr_fun schau ich mir mal an. Ich hab damit zwar noch nie gearbeitet, aber man lernt ja immer was dazu. 🙂
    Auf eine Hilfsfunktion wollte ich eigentlich verzichten. Wenn alle Stricke reißen werde ich aber wohl trotzdem darauf zurückkommen.

    Ciao


Log in to reply