UnicodeString



  • hallo an das Forum,

    und zwar arbeite ich mit dem RadStudioXE4 und möchte in einem UnicodeString auf die einzelnen Zeichen zugreifen bzw. einen kleinbuchstaben durch einen Großbuchstaben am Anfang eines Wortes ersetzen. Da ich auch keinerlei Erfahrung mit UnicodeString habe frage ich hier einmal wie ich an die Sache rangehen muss.

    Oder gibts es eine Funktion die das automatisch erledigt ?

    Meine Zeichenkette sieht zum Beispiel so aus: "hello world, привет мир"
    und soll dann so aussehen: "Hello World, Привет Мир"

    UnicodeString mStr = U"hello world";
    
    	for(int a=0; a < mStr.Length(); a++)
    	{        
                ?
                //mStr[a+1];
    	}
    
    	ShowMessage(mStr);
    
        //Ergebniss soll sein: Hello World";
    


  • Einzelne UnicodeString -Zeichenbesteht haben den Datentyp _TCHAR . Je nach Anwendungseinstellung ist das entweder char (Anwendung unterstützt kein Unicode) oder wchar_t . Für die Uppercase-Konvertierung kannst du entweder toupper oder towupper benutzen.



  • hab da mal noch eine Frage:

    sind denn diese beiden schreibweisen vom ergebniss her identisch bzw. gibts da nen Progblem mit irgendwie ?

    //------------- 1 --------------------
    UnicodeString x;
    UnicodeString mStr = U"hello world";		
    x = mStr[1];	
    x = x.UpperCase();
    
    //------------- 2 --------------------
    UnicodeString x;
    UnicodeString mStr = U"hello world";		
    x = UnicodeString (mStr[1]).UpperCase();
    


  • Nein, das sollte beides gehen (vorausgesetzt, es gibt einen UnicodeString -Konstruktor, der einen _TCHAR entgegennimmt), ist aber etwas umständlich.
    Die einfachste Lösung ist wohl:

    UnicodeString myString = U"hello world!";
    myString[1] = towupper( myString[1] );
    

    Ungetestet.



  • hi,

    ich kann leider diese towupper funktion nicht verwenden weil er mir zum Beispiel das hier dann nicht großmacht "привет мир".

    Bei der anderen Variante funktioniert das aber schon:

    UnicodeString x;
    UnicodeString mStr = U"привет мир";
    x = mStr[1];
    x = x.UpperCase();



  • Kralle schrieb:

    und zwar arbeite ich mit dem RadStudioXE4 und möchte in einem UnicodeString auf die einzelnen Zeichen zugreifen bzw. einen kleinbuchstaben durch einen Großbuchstaben am Anfang eines Wortes ersetzen. Da ich auch keinerlei Erfahrung mit UnicodeString habe frage ich hier einmal wie ich an die Sache rangehen muss.

    Oder gibts es eine Funktion die das automatisch erledigt ?

    Wenn du auf die einzelnen Ziffern in einem UnicodeString zugreifen willst, um sie zu manipulieren (wie etwa, um Groß- in Kleinbuchstaben umzuwandeln), solltest du dir bewußt sein, daß ein UnicodeString UTF-16 verwendet und, genau wie in UTF-8, eine einzelne Ziffer mehrere Zeichen umfassen kann; Details stehen hier.

    Soweit ich weiß, gibt es in der Delphi-RTL keine Funktionen für das Erkennen von Lead- und Trail-Surrogaten in UTF-16 (nur für UTF-8, was erheblich komplizierter ist), aber mit den Informationen von Wikipedia kann man sich die sehr einfach selbst machen:

    bool IsUTF16LeadSurrogate (WideChar lead)
    {
        return lead >= 0xD800 && lead <= 0xDBFF;
    }
    bool IsUTF16TrailSurrogate (WideChar trail)
    {
        return trail >= 0xDC00 && trail <= 0xDFFF;
    }
    int UTF16CharSize (WideChar lead)
    {
        if (IsUTF16TrailSurrogate (lead)) // invalid lead surrogate
            return 0;
        else if (IsUTF16LeadSurrogate (lead))
            return 2;
        else
            return 1;
    }
    

    Mit diesen Funktionen kannst du eine bestimmte Anzahl Ziffern von einem String abtrennen:

    #include <utility>
    
    std::pair<UnicodeString, UnicodeString> SplitChars (const UnicodeString& str, int charsToSplit)
    {
        int nChars = 0;
        int idx = 1;
        int len = str.Length ();
        while (idx <= len && nChars < charsToSplit)
        {
            idx += UTF16CharSize (str[idx]);
            ++nChars;
        }
        return std::make_pair (str.SubString (1, idx - 1), str.SubString (idx, len - (idx - 1)));
    }
    

    Und so könnte man den ersten Buchstaben der Eingabe in einer Edit-Box zu einem Großbuchstaben machen:

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        std::pair<UnicodeString, UnicodeString> spl = SplitChars (Edit1->Text, 1);
        String uppercasedString = spl.first.UpperCase () + spl.second;
        ShowMessage (uppercasedString);
    }
    

    Die Lösung funktioniert für die meisten gängigen Schriftsysteme. Allerdings hat die Win32-Funktion CharUpper() , die von UnicodeString::UpperCase() aufgerufen wird, einige Nachteile:
    - sie setzt voraus, daß die Byte-Zahl einer Ziffer unverändert bleiben muß. Das ist nicht immer der Fall, z.B. bei Ligaturen (fl -> FL) oder beim großen ß (ß -> ẞ)
    - sie unterstützt die Umwandlung in vielen erweiterten Zeichensätzen nicht, etwa in mathematisch-alphanumerischen Zeichen (𝓏 -> 𝒵)

    Aber wenn du das für absurde Sonderfälle hältst, solltest du mit dieser Lösung gut hinkommen.


Anmelden zum Antworten