Question

Je viens de recevoir Delphi 2009 et j'ai déjà lu des articles sur les modifications qui pourraient être nécessaires en raison du passage aux chaînes Unicode. Généralement, il est mentionné que sizeof (char) n'est plus garanti égal à 1. Mais pourquoi cela serait-il intéressant en ce qui concerne la manipulation des chaînes?

Par exemple, si j'utilise AnsiString: = 'Test' et fais la même chose avec une chaîne (qui est maintenant unicode), j'obtiens Length () = 4, ce qui est correct pour les deux cas. Sans l'avoir testé, je suis sûr que toutes les autres fonctions de manipulation de chaîne se comportent de la même manière et décident en interne si l'argument est une chaîne unicode ou autre.

Pourquoi la taille réelle d'un caractère m'intéresse-t-elle si je manipule des chaînes? (Bien sûr, si j'utilise des chaînes comme chaînes et que je ne stocke aucune autre donnée)

Merci pour toute aide!   Holger

Était-ce utile?

La solution

Avec Unicode SizeOf (SomeChar) < > Longueur (SomeChar) . La longueur d'une chaîne est essentiellement inférieure à la somme de la taille de ses caractères . Tant que vous ne supposez pas SizeOf (Char) = 1 ou SizeOf (SomeString [x]) = 1 (puisque les deux sont FALSE maintenant) ou essayez d'échanger des octets avec des caractères , vous ne devriez donc pas avoir de problèmes. Chaque fois que vous faites quelque chose de créatif, Octets sont insérés dans caractères ou Chaînes , vous devrez utiliser AnsiString .

(SizeOf (SomeString) est toujours 4 quelle que soit sa longueur puisqu'il s'agit essentiellement d'un pointeur doté de la magie du compilateur.)

Autres conseils

Les personnes convertissent souvent implicitement des caractères en octets dans l'ancien code Delphi sans vraiment y penser. Par exemple, lors de l'écriture dans un flux. Lorsque vous écrivez une chaîne dans un flux, vous devez spécifier le nombre d'octets que vous écrivez, mais les utilisateurs transmettent souvent le nombre de caractères à la place. Voir ce message de Chris Bensen . pour un autre exemple.

Une autre façon dont les gens font souvent cette conversion implicite et un code plus ancien consiste à utiliser une & "chaîne &"; pour stocker des données binaires. Dans ce cas, ils veulent en réalité des octets, mais le type de données attend des caractères. D2009 a un meilleur type pour cela .

Je n'ai pas essayé Delphi 2009, mais j'utilise fpc, qui bascule également lentement vers Unicode. Je suis sûr à 95% que tout ce qui est présenté ci-dessous est également valable pour Delphi 2009

Dans fpc (lors de la prise en charge de l’unicode), les fonctions telles que 'length' prendront en compte la page de code. Ainsi, il retournera la longueur de la chaîne comme le ferait un "humain". S'il y a - par exemple - deux caractères chinois, qui prennent tous deux deux octets de mémoire en unicode, la longueur retournera 2, puisqu'il y a deux caractères dans la chaîne. Mais la chaîne prendra 4 octets de mémoire. (+ la mémoire pour le décompte de références et le # 0 initial, mais cela mis à part)

Ce que vous ne pouvez plus faire, c’est ceci:

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

Parce que ce code va - dans l'exemple des deux caractères chinois - écrire les deux caractères incorrects. À savoir les deux octets qui font partie du premier caractère "réel".

En bref: Length () ne renvoie plus le nombre d'octets alloués à la chaîne, mais le nombre de caractères. (Avant le passage en unicode, ces deux valeurs étaient égales)

La taille réelle d’un caractère ne devrait pas avoir d’importance, à moins que vous ne manipuliez les octets.

  

(Bien sûr, si j'utilise des chaînes en tant que chaînes et ne stocke aucune autre donnée)

C’est l’essentiel, VOUS n’utilisez pas de chaînes de caractères à d’autres fins, mais certaines personnes le font. Ils utilisent des chaînes comme des tableaux, alors ils (et c’est-à-dire moi) auraient besoin de vérifier tous ces usages pour s’assurer que rien n’est brisé ...

N'oublions pas qu'il y a des moments où cette conversion n'est pas vraiment souhaitée. Dites par exemple pour stocker un GUID dans un enregistrement. Le guid ne peut contenir que des caractères hexadécimaux, suivis des - et des crochets ... leur utilisation occupant deux fois plus d'espace peut avoir un impact considérable sur le code existant. Bien sûr, la solution la plus simple est de les remplacer par AnsiString et de gérer les avertissements du compilateur si vous manipulez des chaînes.

Cela peut poser problème si vous passez des appels API Windows. Si vous avez un code existant qui augmente ou diminue de str [0] pour en modifier la longueur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top