LowerCase?



  • hi!
    also ich muss mich wohl noch an VC++ gewöhnen, ich will alle zeichen eines Strings in kleinbuchstaben umwandeln..da

    <string.h>
    

    sowas aber nicht unterstützt (oder doch?!?!?) hab ich früher (zu BCB Zeiten) immer auf

    String
    

    zurückgegriffen, dort gab es nämlich sowas. bsp:

    String test;
    test="Hallo Du!";
    test.LowerCase();
    

    aber was soll ich nun tun? wenn ich

    <String.h>
    

    include bekomm ich keinen Fehler, doch ich kann kein

    String
    

    Objekt anlegen. Gibts da einen ausweg oder muss ich mir mein LowerCase selber schreiben? 😞

    thx&&cya



  • Ich versteh' das jetzt mal so, dass du MFC verwenden willst. Da geht das dann z.B. so:

    CString s = "Hallo du.";
    s.MakeLower();
    

    String.h brauchst du dann net mehr.

    MfG
    Happosai



  • 😞
    leider wollte ich kein MFC bnutzen, des programm is mit WinAPI geschrieben, da ich jedoch schonmal ein header problem hatte und dieser thread ins MFC forum verschoben wurde, hab ich es nun von anfang an hier rein gepostet.
    aber ansonsten mach ich mir eben ne eigene LowerCase. trotzdem THX@Happosai



  • soo..hab nun meine eigene LowerCase funktion, für die, dies interessiert:

    #include <string>
    //...
    string MakeLower(string text)
    {
     for(int i=0;i<text.length();i++) 
     {
      if(text[i]>64 && text[i]<91)  //Handelt es sich um einen Grossbuchstaben?
      {
       text[i]+=32; //Umwandlung in einen Kleinbuchstaben
      }
     }
     return text;
    }
    


  • Kein MFC, aber im MFC-Forum posten ????
    Grrr, /me hälts langsam nimmer aus!!
    VERSCHOBEN!!!



  • wie wärs mit:

    template<class T>
    void toLower(const T& str)
    {
      typename T::iterator i=str.begin();
      typename T::iterator end=str.end();
      while(i!=end)
      {
        *i=tolower(*i);
        ++i;
      }
    }
    

    mhm, eigentlich könnte man noch locale einbauen, dazu bin ich jetzt aber zu faul.



  • Hallo, also ich seh da bei deinem code nicht wirklich durch, weshalb ich eigentlich auch nur codes schreibe die ich auch nachvollziehen kann, wie folgenden:

    void String::toLowerCase() {
    
        char *p = value;
        while (p[0] != '\0') {
            if (p[0] <= 90 && p[0] >= 65) p[0] += 32;
            p++;
        }
    }
    

    Also das ist meine Version die ich auch verstehe, aber ich möchte diese für mich komplizierte Methode von dir auch verstehen, also könntest du sie bitte erklären Shade of Your?
    Danke!

    [ Dieser Beitrag wurde am 16.04.2003 um 15:20 Uhr von Pogo editiert. ]



  • Die ist gar nicht kompliziert, schau mal in Deinem Lieblings-C++ Buch im Kapitel "Templates" nach, dann wirst Du das schon verstehen!

    Shade: Aber wäre nicht ein

    while(i++ != end)
        *i=tolower(*i);
    

    geringfügig schöner? 🙂

    edit: *bg* Sorry, schweres Mitdenkdefizit, viel Sinn würde das nicht gerade machen... 🙂

    [ Dieser Beitrag wurde am 16.04.2003 um 17:09 Uhr von nman editiert. ]



  • Naja, werde ich wohl tun müssen... 🙂

    [ Dieser Beitrag wurde am 16.04.2003 um 15:28 Uhr von Pogo editiert. ]



  • Keine Ahnung wo die implementiert ist, deklariert ist sie jedenfalls in cctype



  • Ok, danke.



  • Original erstellt von Shade Of Mine:
    **```cpp
    template<class T>
    void toLower(const T& str)
    {
    typename T::iterator i=str.begin();
    typename T::iterator end=str.end();
    while(i!=end)
    {
    *i=tolower(*i);
    ++i;
    }
    }

    Wenn du schon Iteratoren verwendest dann sinnvoll:

    template<class Iterator>
    void MyToLower(Iterator b, Iterator e)
    {
      while(b != e)
      {
        *b = tolower(*b);
      }
      ++b;
    }
    int main()
    {
      string str = "asAölÖLKDasdlkölöKAKJLSDök";
      tolower(str.begin(), str.end());
    }
    

    [ Dieser Beitrag wurde am 16.04.2003 um 16:13 Uhr von HumeSikkins editiert. ]



  • Hmm der Internet Explorer stinkt, der will mich net einloggen.
    Hmm kann da mal jemand die Codetags richtig machen?



  • @Lars
    Und wo ist da der Vorteil gegenüber std::transform?

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <cctype>
    using namespace std;
    int main()
    {   
        string s("HALLO");
        transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower);
        cout << s << endl;
    }
    

    Shades Variante hat doch gerade den Vorteil, dass sie äuerlich *keine* Iteratoren verwendet.



  • Original erstellt von HumeSikkins:
    **```cpp
    transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower);

    zu welchen problem kann es kommen wenn ich den cast weglasse?
    ahja und sonst zu den cast, das man statt eines reinterpret_cast ein c-cast schreib kann ich noch verstehen
    aber wieso hier?

    [QUOTE]Original erstellt von Shade Of Mine:
    [QB]wie wärs mit:

    template<class T>
    void toLower(const T& str)
    {
      typename T::iterator i=str.begin();
      typename T::iterator end=str.end();
      while(i!=end)
      {
        *i=tolower(*i);
        ++i;
      }
    }
    

    hier gibt probleme mir den const
    und den großen vorteil von templates sehe ich hier nicht



  • Und wo ist da der Vorteil gegenüber std::transform?

    Ich vermute, das Lars std::transform gar nicht kannte.

    und nman's Version funzt wenn ich grade keinen Knoten im Kopf hab nicht. Wann soll den der erste Buchstabe bearbeitet werden?



  • zu welchen problem kann es kommen wenn ich den cast weglasse?

    Mehrdeutigkeiten, wenn beim Aufruf mehrere tolower-Überladungen sichtbar sind.
    Damit hatte ich bisher aber nur im Zusammenhang mit einigen gcc-Versionen Probleme.

    ahja und sonst zu den cast, das man statt eines reinterpret_cast ein c-cast schreib kann ich noch verstehen
    aber wieso hier?

    Hier wäre definitiv ein static_cast angebrachter. Der C-Code ist Mist, so wie 90% der Sachen die ich poste 😃

    hier gibt probleme mir den const
    und den großen vorteil von templates sehe ich hier nicht

    und strenggenommen sollte man jedes Zeichen zumindest noch nach unsigned char casten.



  • Original erstellt von Helium:
    **Ich vermute, das Lars std::transform gar nicht kannte.
    **

    Richtig vermutet. Weshalb dieser böse Cast hier? Kannst du mir das mal erklären, sehe std::transform zum ersten mal.

    @iterator-verstecken:
    Iteratoren sind ja dazu da um Algorithmen wiederverwendbarer zu machen. So funktioniert das nur wenn die String-Klasse iterator genau so wie die STL unterstüzt. So lässt sich die Funktion kaum wiederverwenden. Anderfalls könnte man z.B. mit einer völlig fremden Stringklasse sowas o.ä. machen:
    XX::String specialStringClass;
    ToLower(speciealStringClass.getCStr(), speciealStringClass.getCStr()+speciealStringClass.length());

    Warum sollte man die Iteratoren verstecken 😕 😕



  • Warum sollte man die Iteratoren verstecken

    Ganz einfach, weil Iteratoren eine Abstraktion sind, die man nicht immer haben will. Natürlich ist es cleverer eine generelle Funktion (wie z.B. sort) so generisch wie möglich zu machen, in *konkreten* Fällen ist ein schönes Interface aber auch nicht zu verachten. Deshalb gibt es z.B. viele Leute die sich ein ein-Parameter-sort für Arrays basteln. Und das selbe gilt auch für strings.
    Ein:

    string s;
    tolower(s);
    

    ist IMHO deutlich klarer, als ein:

    string s;
    tolower(s.begin(), s.end());
    

    Wobei man ersteres sicher über letzteres implementiert.

    So lässt sich die Funktion kaum wiederverwenden

    Noch vor die Wiederverwendbarkeit sollte man erstmal die Verwendbarkeit stellen. Auch wenn die Marketingabteilung da anderer Meinung ist 🙂

    Weshalb dieser böse Cast hier? Kannst du mir das mal erklären, sehe std::transform zum ersten mal.

    An welcher Stelle reicht dir meine vorherige Erklärung nicht?



  • Hmm..sind ja doch noch recht viele Vorschläge für ein "toLower" gekommen, doch bei der Funktion die ich mir geschrieben habe, zur Erinnerung:

    string MakeLower(string text) // hab noch etwas geringfügig verändert
    {
     for(int i=0;i<=text.length();i++) 
     {
      if(text>64 && text[i]<91)  //Handelt es sich um einen Grossbuchstaben?
      {
       text[i]+=32; //Umwandlung in einen Kleinbuchstaben
      }
     }
     return text;
    }
    

    Gibt es jetzt folgendes Problem, ich rufe MakeLower in meinem Programm folgendermaßen auf:

    ..
    getline(Q,line);
    SearchHTMLTag(line);
    //--------------------------------------------------------------------------
    int SearchHTMLTag(string data)
    {
     int pos;
     data=MakeLower(data);
     pos=data.find("<html>");
     if(pos!=string::npos)
     { return pos; }
     else return -1;
    }
    

    nun wird mein Programm aber abgebrochen, mit folgender Fehlermeldung:
    [i]Unhandled exception in Project1.exe: 0xC0000005: Access Violation*
    Der Debugger zeigt mir dann die datei XSTRING (oder so ähnlich)..was ist an meinem MakeLower falsch? Mit Konstanten gehts wunderbar.Sollte ich lieber eine Funktion verwenden die ihr hier gepostet habt? wenn ja, warum?

    ich hoffe hier schaut nochmal einer vorbei. 🙄

    thx && cya


Anmelden zum Antworten