A
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.