Frage

Ich habe gerade Delphi 2009 erhalten und zuvor einige Artikel über Änderungen gelesen, die aufgrund der Umstellung auf Unicode-Strings erforderlich sein könnten.Meistens wird erwähnt, dass sizeof(char) nicht mehr garantiert 1 ist.Aber warum sollte dies im Hinblick auf die String-Manipulation interessant sein?

Wenn ich beispielsweise einen AnsiString:='Test' verwende und dasselbe mit einem String (der jetzt Unicode ist) mache, erhalte ich Length() = 4, was für beide Fälle korrekt ist.Ohne es getestet zu haben, bin ich sicher, dass sich alle anderen String-Manipulationsfunktionen genauso verhalten und intern entscheiden, ob das Argument ein Unicode-String oder etwas anderes ist.

Warum sollte die tatsächliche Größe eines Zeichens für mich von Interesse sein, wenn ich Zeichenfolgenmanipulationen vornehme?(Natürlich, wenn ich Strings als Strings verwende und keine anderen Daten speichere)

Vielen Dank für jede Hilfe!Holger

War es hilfreich?

Lösung

Mit Unicode SizeOf(SomeChar) <> Länge(SomeChar).Im Wesentlichen die Länge von a Zeichenfolge ist kleiner als die Summe seiner Größe verkohlenS.Solange Sie nicht davon ausgehen SizeOf(Char) = 1, oder SizeOf(SomeString[x]) = 1 (da beides sind FALSCH jetzt) ​​oder versuchen Sie es auszutauschen Bytes mit verkohlens, dann sollten Sie keine Probleme haben.Überall dort, wo Sie etwas Kreatives tun Bytes in Verkohlens oder Zeichenfolges, dann müssen Sie verwenden AnsiString.

(SizeOf(SomeString) ist unabhängig von der Länge immer noch 4, da es sich im Wesentlichen um einen Zeiger mit etwas Compiler-Magie handelt.)

Andere Tipps

Die Menschen wandeln oft implizit von Zeichen zu Zeichen in altem Code Delphi, ohne wirklich darüber nachzudenken. Wenn zum Beispiel in einen Stream zu schreiben. Wenn Sie einen String in einen Stream zu schreiben, müssen Sie die Anzahl der Bytes geben Sie schreiben, aber die Leute oft passieren, anstatt die Zeichenanzahl. Siehe diesen Beitrag von Chris Bensen für ein anderes Beispiel.

Eine andere Möglichkeit, die Menschen oft diese implizite Konvertierung machen und ältere Code ist durch einen „String“ mit binären Daten zu speichern. In diesem Fall wollen sie tatsächlich Bytes, aber der Datentyp erwartet Zeichen. D2009 hat eine bessere Art für diese .

Ich habe nicht versucht Delphi 2009, aber verwenden fpc, die auch langsam auf Unicode umgeschaltet wird. Ich bin 95% sicher, dass alles unter gilt auch für Delphi 2009

In fpc (wenn Unicode-Unterstützung) wird es sein, so dass Funktionen wie ‚Länge‘, um die Codepage in Betracht. So wird es die Länge der Zeichenfolge als ‚menschlichen‘ zurückkehren würde es sehen. Wenn es - zum Beispiel - zwei chinesische Schriftzeichen, dass beide nehmen zwei Byte Speicher in Unicode, wird Länge 2 zurückkehren, da es zwei Zeichen in der Zeichenfolge. Aber der String 4 Byte Speicherplatz verbrauchen. (+ Der Speicher für die Referenzzählung und die führenden # 0, aber abgesehen davon)

Was Sie kann nicht mehr tun, ist dies:

var p : pchar;
begin
  p := s[1];
  for i := 0 to length(string)-1 do
    begin
    write(p);
    inc(p);
    end;      
end;

Da dieser Code - in den beiden chinesischen Zeichen Beispiel - die falschen zwei Zeichen schreiben. Nämlich die beiden Bytes, die sind Teil des ersten ‚echten‘ Charakters.

Kurz gesagt: Länge () gibt nicht die Anzahl der Bytes für die Zeichenfolge zugewiesen mehr, aber die Menge von Zeichen. (Vor der Umstellung auf Unicode, diese beiden Werte waren gleich einander)

Die tatsächliche Größe eines Zeichens sollte keine Rolle spielen, wenn Sie die Manipulation auf Byte-Ebene tun.

  

(Natürlich, wenn ich Strings als Strings verwenden und keine anderen Daten zu speichern)

Das ist der entscheidende Punkt, die Sie nicht verwenden Strings für andere Zwecke, aber einige Leute tun. Sie verwenden Strings wie Arrays, so dass sie (und das ist mich eingeschlossen) müssten alle solche Anwendungen überprüfen, dass nichts zu machen ist gebrochen ...

Nicht vergessen, dass es Zeiten gibt, wenn diese Umwandlung nicht wirklich erwünscht ist. Angenommen, für eine GUID in einem Datensatz beispielsweise zu speichern. Die GUID kann nur hexadezimale Zeichen enthalten plus - und Klammern ... so dass sie doppelt so viel Platz in Anspruch nehmen kann einen großen Einfluss auf den bestehenden Code machen. Sicher, die einfache Lösung ist, sie zu Ansistring, zu ändern und mit den Compiler-Warnungen umgehen, wenn man auf sie eine beliebige String-Manipulation zu tun.

Es kann ein Problem sein, wenn Sie Windows-API-Aufrufe. Oder wenn Sie Legacy-Code, der tut inc oder Dezember str [0] seine Länge ändern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top