Ich wollte noch einmal was zu meinen vorher beschriebenen merkwürdigen Ergebnissen bei VB6 unter japanischen Systemen schreiben. Auf Grund der Länge habe ich ihn wieder in 2 Teile aufgeteilt.
Teil 1:
Ich dachte vorher, dass es bei der unter Windows verwendeten ANSI-Kodierung immer so ist, dass jedes Byte genau ein Zeichen darstellt. Dies ist aber anscheinend bei der unter japanischen Systemen verwendeten Kodierung nicht der Fall. Dies erkennt man beispielsweise, wenn man die Windows Zeichentabelle startet und bei Zeichensatz "Windows: Japanisch" auswählt. Bei den normalen Zeichen steht steht in der Statuszeile immer sowas wie "U+0078 (0x78)", also erst der Unicode-Wert des Zeichens und dann der Wert, der das Zeichen unter dem eingestellten länderspezifischen ANSI-Zeichensatz hat. Bei einigen Zeichen steht aber z. B. "U+8AB2 (0x89DB): Einheitliches CJK-Ideogramm". Für dieses Zeichen werden dann also auch im ANSI-Zeichensatz 2 Bytes verwendet. Wenn man jetzt unter einem deutschen Windows den Editor öffnet, "Test äö" schreibt, als ANSI speichert und unter einem japanischen System öffnet, steht dort dann dieser Text (das letzte Zeichen ist ein CJK-Ideogramm, um des darzustellen, müssen die asiatischen Schriften installiert sein). Der Text hat dort dann also 6 Zeichen (im deutschen Windows waren es ja 7).
VB benutzt natürlich dann das gleiche System, um beispielsweise Dateien einzulesen, wenn man diese direkt in einen String einliest (wie es wahrscheinlich auch die meisten machen werden). Wenn man also schreibt:
Dim Text As String
Open "Datei.txt" For Binary As 1
Text = String(LOF(1), Chr(0))
Get 1, , Text
Close 1
MsgBox Text Dann gibt VB in der MessageBox den Text mit dem einen CJK-Ideogramm aus. Wenn man den ByteWert mit MsgBox Asc(Mid(Text, 6, 1)) abfrägt, ergibt das -6922, also vorzeichenbereinigt 58614 (E4F6), der 2-Byte-Code für dieses Zeichen, nicht der Byte-Wert des ersten Zeichens an der Stelle 6. Auf einem deutschen Windows würde das dagegen 228 (E4) ergeben, das erste der beiden Bytes.
Wenn man jetzt also eine Datei binär einlesen will und dann wissen will, welcher Wert ein Byte an irgend einer Stelle hat, kann man das so nicht machen, da sich ja beim Vorkommen solcher erweiterter Zeichen die Stellen verschieben. Man müsste dann einen binären String verwenden, indem man die Datei erst in ein Byte-Array einliest und dieses dann einem String zuweist:
Dim Text As String, tempArr() As Byte
Open "Datei.txt" For Binary As 1
ReDim tempArr(LOF(1) - 1)
Get 1, , tempArr
Close 1
Text = tempArr Zum Bearbeiten des Strings muss man dann allerdings die Byte-basierten String Funktionen benutzten, also alle die am Schluss ein B enthalten (wie ChrB, AscB, MidB, LenB, InStrB usw.)
MsgBox AscB(MidB(Text, 6, 1)) In diesem Fall gibt die MessageBox auch auf einem japanischen Windows den Wert 228 aus.
Dieses Verfahren sollte man für alle Strings verwenden, die binäre Daten enthalten (also nicht für Textdarstellungszwecke , denn hier können ja Unicode-Zeichen vorkommen, und die sind ja nur in einem Unicode-String eindeutig definiert. Also wenn man auch auf einem ausländischen Windows ein "ä" darstellen will, muss man das mit ChrW(228) machen, nicht mit Chr(228), denn die normale Chr-Funktion erstellt ja ein Unicode-Zeichen aus dem angegebenen ANSI-Wert. Wobei das "ä" dann wahrscheinlich als "a" angezeigt wird, wegen der fehlenden Unicode-Unterstützung der VB6-Steuerelemente). Wenn man jetzt eine UTF-8 Datei einliest, kann man diese dann ja mit einer geeigneten Funktion noch in das "echte" Unicode-Format umwandeln, sodass man mit dem String als Text ganz normal arbeiten kann.
Bitte Teil 2 weiterlesen.
Beitrag wurde zuletzt am 23.05.09 um 18:07:50 editiert. |