[Kurzartikel] Find() mit CString
-
Dieser Text bezieht sich auf die Find() Methode der CString Klasse.
Daten/Zeichendarstellung mit CString
Dass CString eigentlich Null-Terminierend ist (also '\0' oder 0x00) ist nicht ganz korrekt. CString kann beliebige Daten aufnehmen, die Darstellung endet jedoch beim ersten \0 Zeichen (oder sonstigen nicht darstellbaren Zeichen/Steuerzeichen).Beispiel:
CString str = getDataFromAnySource(); //Z1 AfxMessageBox(str); // Z2 int iLen = str.GetLength(); // Z3 int iPos = str.Find('o', 0); // Z4 // angenommen, es werden die Byte Daten mit der get..() Methode zurückgegeben: // 48 65 6C 6C 6F 00 57 6E 72 6C 64 (-> "Hello\0World") // // ... dann gibt die Box (Zeile Z2) den String "Hello" aus // ... dann gibt iLen den Wert 11. // ... dann gibt iPos den Wert -1.
Erkenntnis:
GetLengh() funktioniert korrekt, weil es die korrekte Stringlänge zurückgibt.
Find() funktioniert nicht, weil -1 anstatt 8 zurückgegeben wird. Jetzt kann man sagen "ok ist klar, bei 0x00 ist die Zeichenkette fertig. Aber....Angenommen, mit der get..() Methode wird nun die Zeichenkette "HélloWorld" der CString-Variable zugewiesen:
Da 'é' ausserhalb des ANSI-ASCII-Bereichs liegt (also im 8-ten ASCII Bit), wird dies je nach Regionen- & Ländereinstellungen anders interpretiert (Codepages).Im Fall "Einstellungen = Japanisch" ist es so, dass diese Sonderzeichen nicht angezeigt werden, anders angezeigt werdeb oder das und das nachfolgende Zeichen sogar modifiziert behandelt werden:
CString str = getDataFromAnySource(); //Z1 AfxMessageBox(str); // Z2 int iLen = str.GetLength(); // Z3 int iPos = str.Find('o', 0); // Z4 // angenommen, es werden die Byte Daten mit der get..() Methode zurückgegeben: // 48 E9 6C 6C 6F 20 57 6E 72 6C 64 (-> "Héllo World") // // ... dann gibt die Box (Zeile Z2) den String "H" aus, weil es bei 'é' abbricht. // ... dann gibt iLen den Wert 11. // ... dann gibt iPos den Wert -1.
Mich stört nun, dass GetLength(), SetAt() usw. zwar funktioniert, Find() jedoch nicht!
Man muss nun das Problem zum Beispiel so umgehen, dss man zuerst sämtliche Daten im CString in ein Byte-Array abfüllt und dann jeden Datenwert mit dem zu suchenden Zeichen vergleicht:
CString str = getDataFromAnySource(); //Z1 CBYteArray baData; char chrToFind = 'W'; //0x57 // abfüllen for(int i=0; i<str.GetLength(); i++){ baData.Add (BYTE) str.GetAt(i)); } // suchen for(int j=0; j<baData.GetSize(); j++){ if( baData.GetAt(j) == (BYTE) chrToFind){ return j; } } // else return -1;
Dies könnte man nun noch optimieren, in dem man direkt CString::GetAt() mit dem Zielzeichen vergleicht.
Comments welcome
-
Hallo,
mich interesiert was passiert wenn ich in einem langen string kombinierte zeichen habe, also Unicode und ANSI? Z.B. Deutsch und Chinesisch, oder irgendeine andere Sprache aus dem Asiatischen Raum!
Wie würde das dann funktionieren mit dem suchen??? Und wie wird die Länge des Strings zurückgegeben?
mfg
pixel