Types chaîne (Object Pascal)

De Appmethod Topics
Aller à : navigation, rechercher

Remonter à Types de données, variables et constantes - Index


Cette rubrique décrit les types de données chaîne disponibles dans le langage Object Pascal. Les types suivants sont traités :

Tous les types chaîne décrits dans cette rubrique sont pris en charge par les compilateurs Object Pascal pour les plates-formes de bureau, mais les compilateurs Object Pascal pour les plates-formes mobiles prennent seulement en charge le type chaîne par défaut (UnicodeString). En outre, avec les compilateurs Object Pascal pour les plates-formes mobiles, les chaînes sont basées sur 0 et sont immuables ; pour manipuler les chaînes, utilisez les fonctions TStringHelper, qui sont fournies à cet effet. Pour de plus amples informations, voir Migration du code Object Pascal en mobile depuis le bureau.

A propos des types chaîne

Une chaîne représente une suite de caractères. Object Pascal prend en charge les types chaîne prédéfinis suivants.

Types chaîne

Type Longueur maximale Mémoire nécessaire Utilisé pour

ShortString

255 caractères

2 à 256 octets

Compatibilité descendante

AnsiString

~2^31 caractères

4 octets à 2 Go

Caractères sur 8 bits (ANSI), DBCS ANSI, MBCS ANSI, caractères Unicode, etc.

UnicodeString

Remarque : Dans Appmethod, string est un alias pour UnicodeString.

~2^30 caractères

4 octets à 2 Go

Caractères Unicode, caractères sur 8 bits (ANSI), serveurs multi-utilisateurs et applications multilingues

UnicodeString est le type chaîne par défaut.

WideString

~2^30 caractères

4 octets à 2 Go

Caractères Unicode ; serveurs multi-utilisateurs et applications multilingues. WideString n'est pas pris en charge par les compilateurs Object Pascal pour les plates-formes mobiles, mais est pris en charge par les compilateurs Object Pascal pour les plates-formes de bureau. L'utilisation de UnicodeString est généralement préférée à WideString.}}

Remarque : Le type chaîne par défaut est UnicodeString. Dans la plupart des cas, UnicodeString est le type préféré. Le type string est un alias pour UnicodeString.

Les types chaîne peuvent être combinés dans les affectations et les expressions ; le compilateur effectue automatiquement les conversions nécessaires. Par contre, les chaînes passées par référence à une fonction ou à une procédure (comme les paramètres var et out) doivent être du type approprié. Les chaînes peuvent être explicitement transtypées dans un type chaîne différent. Toutefois, le transtypage d'une chaîne multi-octets en une chaîne mono-octet peut conduire à des pertes de données.

Voici quelques valeurs de types chaîne spéciaux :

  • Les AnsiStrings à page de codes sont définis comme suit :
Type mystring = Type AnsiString(CODEPAGE)
C'est un AnsiString ayant une affinité à maintenir ses données internes dans une page de codes spécifique.
  • Le type RawByteString est type AnsiString($FFFF). RawByteString permet le passage des données chaîne de toute page de codes sans conversion de page de codes. RawByteString doit seulement être utilisé comme un paramètre de type value ou const ou un type de retour d'une fonction. Il ne doit jamais être passé par référence (passé par var) et ne doit jamais être instancié comme une variable.
  • UTF8String représente une chaîne encodée en UTF-8 (nombre variable d'octets Unicode). C'est un type AnsiString avec une page de codes UTF-8.

Le mot réservé string fonctionne comme un identificateur de type chaîne général. Par exemple :

var S: string;

crée une variable S contenant une chaîne. Sur la plate-forme Win32, le compilateur interprète string (quand il apparaît sans être suivi d'un nombre entre crochets) comme désignant UnicodeString.

Sur la plate-forme Win32, vous pouvez utiliser la directive {$H-} pour transformer string en ShortString. C'est une technique potentiellement utile lors de l'utilisation d'anciens codes Turbo Pascal ou Object Pascal 16 bits avec vos programmes actuels.

Notez que le mot clé string est aussi utilisé lors de la déclaration de types ShortString de longueurs spécifiques (voir Chaînes courtes ci-dessous).

Les comparaisons de chaînes sont définies par l'ordre des éléments dans les positions correspondantes. Avec des chaînes de longueurs différentes, chaque caractère de la chaîne la plus longue n'ayant pas de caractère correspondant dans la chaîne la plus courte prend la valeur "supérieur à". Par exemple, 'AB' est supérieure à 'A' ; c'est-à-dire que 'AB' > 'A' renvoie True. Les chaînes de longueur nulle représentent les valeurs les plus petites.

Il est possible d'indexer une variable chaîne comme un tableau. Si S est une variable chaîne non UnicodeString et i, une expression entière, S[i] représente le nième octet dans S, qui peut ne pas être le nième caractère ou un caractère entier pour une chaîne de caractères multi-octets (MBCS). De façon similaire, l'indexation d'une variable UnicodeString résulte en un élément qui peut ne pas être un caractère entier. Si la chaîne contient des caractères du BMP (Basic Multilingual Plane), tous les caractères sont sur 2 octets et l'indexation de la chaîne obtient ainsi des caractères. Toutefois, si certains caractères ne sont pas dans le BMP, un élément indexé peut être une paire de substitution, pas un caractère entier.

La fonction standard Length renvoie le nombre d'éléments d'une chaîne. Comme indiqué ci-dessus, le nombre d'éléments ne correspond pas nécessairement au nombre de caractères. La procédure SetLength ajuste la longueur d'une chaîne. Notez que la fonction SizeOf renvoie le nombre d'octets utilisés pour représenter une variable ou un type. Sachez que SizeOf renvoie le nombre de caractères d'une chaîne seulement pour une chaîne courte. SizeOf renvoie le nombre d'octets d'un pointeur pour tous les autres types de chaîne, puisque ce sont des pointeurs.

Pour une chaîne courte ou AnsiString, S[i] est de type AnsiChar. Pour un WideString, S[i] est de type WideChar. Pour les locales utilisant un octet (locales occidentales), MyString[2] := 'A'; assigne la valeur A au second caractère de MyString. Le code suivant utilise la fonction standard UpCase pour convertir MyString en majuscule :

var I: Integer;
begin
  I := Length(MyString);
  while I > 0 do
  begin
    MyString[I] := UpCase(MyString[I]);
    I := I - 1;
  end;
end;

Soyez prudent avec l'indexation des chaînes de cette manière, car si vous écrivez au-delà de la fin d'une chaîne, vous provoquez des violations d'accès. De même, évitez de transmettre en paramètre var des index de chaîne car cela produirait un code inefficace.

Vous pouvez assigner à une variable la valeur d'une constante chaîne ou de toute expression renvoyant une chaîne. La longueur de la chaîne change de manière dynamique lors de l'affectation. Exemples :

MyString := 'Hello world!';
MyString := 'Hello' + 'world';
MyString := MyString + '!';
MyString := ' '; { space }
MyString := '';  { empty string }

Chaînes courtes

Un ShortString compte de 0 à 255 caractères mono-octet. Si la longueur d'un ShortString peut changer dynamiquement, 256 octets de mémoire lui sont alloués statiquement. Le premier octet stocke la longueur de la chaîne, les 255 octets suivants sont disponibles pour les caractères. Si S est une variable ShortString, Ord(S[0]) renvoie, comme Length(S), la longueur de S ; l'affectation d'une valeur à S[0], comme l'appel de SetLength, change la longueur de S. ShortString est maintenu seulement pour la compatibilité descendante.

Le langage Object Pascal prend en charge les types de chaîne courte, des sous-types de ShortString dont la longueur maximale se situe entre 0 et 255 caractères. Ils sont simplement désignés par un nombre entre crochets suivant le mot réservé string. Par exemple :

var MyString: string[100];

crée une variable appelée MyString dont la longueur maximale est de 100 caractères. Cela revient aux déclarations suivantes :

type CString = string[100];
var MyString: CString;

Les variables déclarées ainsi allouent seulement la mémoire nécessaire au type, c'est-à-dire la longueur maximale plus un octet. Dans notre exemple, MyString utilise 101 octets, à comparer aux 256 octets d'une variable ayant le type prédéfini ShortString.

Quand vous assignez une valeur à une variable chaîne courte, la chaîne est tronquée si elle dépasse la longueur maximale du type.

Les fonctions standard High et Low opèrent sur les identificateurs et les variables de type chaîne courte. High renvoie la longueur maximale du type chaîne courte alors que Low renvoie zéro.

AnsiString

AnsiString représente une chaîne allouée dynamiquement dont la longueur maximale n'est limitée que par la mémoire disponible.

Une variable AnsiString est une structure contenant des informations de chaîne. Quand la variable est vide (c'est-à-dire quand elle contient une chaîne de longueur nulle), le pointeur vaut nil et la chaîne n'utilise pas de mémoire supplémentaire. Quand la variable est non vide, elle pointe sur un bloc de mémoire alloué dynamiquement qui contient la valeur de la chaîne. Cette mémoire est allouée sur le tas mais sa gestion est entièrement automatique et ne nécessite pas de codage. La structure AnsiString contient un indicateur de longueur 32 bits, un compteur de références 32 bits, une longueur de données 16 bits indiquant le nombre d'octets par caractère et une page de codes 16 bits.

Une variable AnsiString représente une chaîne mono-octet. Avec un jeu de caractères sur un seul octet (SBCS), chaque octet d'une chaîne représente un seul caractère. Dans un jeu de caractères multi-octets (MBCS), les éléments sont toujours des octets uniques, mais certains caractères sont représentés par un octet et d'autres par plusieurs octets. Les jeux de caractères multi-octets, en particulier les jeux de caractères sur deux octets (DBCS), sont fréquemment utilisés pour les langues asiatiques. Une variable AnsiString peut contenir des caractères MBCS.

L'indexation de AnsiString est basée sur 1. L'indexation des chaînes multi-octets n'est pas fiable, puisque S[i] représente le nième octet (pas nécessairement le nième caractère) de S. Le nième octet peut être un caractère unique ou une partie d'un caractère. Toutefois, les fonctions standard de gestion des chaînes AnsiString ont un équivalent multi-octet qui implémente aussi l'ordre des caractères en tenant compte de la localisation. Le nom des fonctions multi-octets commence généralement par Ansi-. Ainsi, la version multi-octet de StrPos est AnsiStrPos. La prise en charge des caractères multi-octets dépend du système d'exploitation et est basé sur les paramètres régionaux en cours.

Puisque les variables AnsiString ont des pointeurs, plusieurs peuvent référencer la même valeur sans utiliser de mémoire supplémentaire. Le compilateur utilise ceci pour économiser les ressources et exécuter les affectations plus rapidement. A chaque fois qu'une variable AnsiString est détruite ou qu'une nouvelle valeur lui est assignée, le compteur de références de l'ancien AnsiString (la valeur précédente de la variable) est décrémenté et le compteur de références de la nouvelle valeur (le cas échéant) est incrémenté. Si le compteur de références d'une chaîne atteint zéro, sa mémoire est désallouée. Ce processus est appelé comptage de références. Quand l'indexation est utilisée pour changer la valeur d'un caractère unique d'une chaîne, une copie de la chaîne est effectuée si, et seulement si, son compteur de références est supérieur à un. On parle alors de sémantique copie-sur-écriture.

UnicodeString (le type chaîne par défaut)

Le type UnicodeString est le type chaîne par défaut et représente une chaîne Unicode allouée dynamiquement dont la longueur maximale n'est limitée que par la mémoire disponible.

Dans un jeu de caractères Unicode, chaque caractère est représenté par un ou plusieurs octets. Unicode a plusieurs formats de transformation Unicode qui utilisent des encodages de caractère différents mais équivalents qui peuvent être facilement transformés de l'un à l'autre.

  • En UTF-8, par exemple, les caractères peuvent comporter de 1 à 4 octets. En UTF-8, les 128 premiers caractères Unicode correspondent aux caractères US-ASCII.
  • UTF-16 est un autre encodage Unicode couramment utilisé dans lequel les caractères sont de 2 octets ou 4 octets. La majorité des caractères internationaux appartient au plan multilingue de base et ils peuvent être représentés sur 2 octets. Les autres caractères nécessitent deux caractères à 2 octets, et sont connus sous le terme paires de substitution.
  • UTF-32 représente chaque caractère avec 4 octets.

La plate-forme Win32 prend en charge les jeux de caractères mono-octet et multi-octets, ainsi que Unicode. Le système d'exploitation Windows prend en charge UTF-16.

Pour de plus amples informations, voir Standard Unicode.

Le type UnicodeString a exactement la même structure que le type AnsiString. Les données UnicodeString sont encodées en UTF-16.

Puisque UnicodeString et AnsiString ont la même structure, ils fonctionnent de façon très similaire. Quand une variable UnicodeString est vide, elle n'utilise aucune mémoire supplémentaire. Quand elle n'est pas vide, elle pointe sur un bloc de mémoire alloué dynamiquement qui contient la valeur de la chaîne, et la gestion de la mémoire est alors transparente à l'utilisateur. Les variables UnicodeString utilisent le comptage de références, et deux ou plusieurs d'entre elles peuvent référencer la même valeur sans consommer de mémoire supplémentaire.

Les instances de UnicodeString peuvent indexer les caractères. L'indexation est basée sur 1, comme pour AnsiString.

UnicodeString est compatible en affectation avec tous les autres types chaîne. Toutefois, les affectations entre AnsiString et UnicodeString effectuent les conversions appropriées vers le bas et vers le haut. Notez que l'affectation d'un type UnicodeString à un type AnsiString n'est pas recommandé et peut générer une perte de données.

Object Pascal peut aussi prendre en charge les caractères et les chaînes Unicode par le biais des types WideChar, PWideChar et WideString.

Pour de plus amples informations sur l'utilisation de Unicode, voir Unicode dans Appmethod et Activation des applications pour Unicode.

WideString

Le type WideString représente une chaîne allouée dynamiquement composée de caractères Unicode sur 16 bits. Par certains points, il ressemble à AnsiString. Sur Win32, WideString est compatible avec le type COM BSTR.

WideString est approprié dans les applications COM. Toutefois, WideString n'utilise pas le comptage de références, ainsi UnicodeString est plus flexible et efficace dans d'autres types d'applications.

L'indexation de chaînes multi-octets WideString n'est pas fiable, puisque S[i] représente le nième élément (pas nécessairement le nième caractère) dans S.

Pour Object Pascal, les types Char et PChar sont respectivement les types WideChar et PWideChar.

Remarque : WideString n'est pas pris en charge par les compilateurs Object Pascal pour les plates-formes mobiles, mais est utilisé par les compilateurs Object Pascal pour les plates-formes de bureau.

Manipulation des chaînes terminées par null

Beaucoup de langages de programmation, dont le C et le C++, n'ont pas de type de données chaîne dédié. Ces langages, et les environnements qui ont été construits avec, utilisent des chaînes terminées par null. Une chaîne terminée par null est un tableau de caractères basé sur zéro qui se termine par NULL (#0). Comme le tableau n'a pas d'indicateur de longueur, le premier caractère NULL indique la fin de la chaîne. Vous pouvez utiliser des constructions Object Pascal et des routines spéciales de l'unité SysUtils (voir Routines standard et entrées-sorties) pour gérer les chaînes terminées par null quand vous avez besoin de partager des données avec des systèmes les utilisant.

Par exemple, les déclarations de type suivantes permettent de stocker des chaînes terminées par null :

type
  TIdentifier = array[0..15] of Char;
  TFileName = array[0..259] of Char;
  TMemoText = array[0..1023] of WideChar;

Avec la syntaxe étendue activée ({$X+}), vous pouvez assigner une constante chaîne à un tableau de caractères basé sur zéro, alloué statiquement. (Les tableaux dynamiques ne peuvent pas être utilisés pour cela.) Si vous initialisez une constante tableau avec une chaîne plus courte que la longueur déclarée du tableau, les caractères restants sont définis sur #0.

Utilisation des pointeurs, tableaux et des constantes chaîne

Pour manipuler les chaînes terminées par null, il est souvent nécessaire d'utiliser des pointeurs. (Voir Pointeurs et types pointeur (Object Pascal).) Les constantes chaîne sont compatibles en affectation avec les types PChar et PWideChar qui représentent des pointeurs sur des tableaux terminés par null de valeurs Char et WideChar. Par exemple :

var P: PChar;
  ...
P := 'Hello world!'

fait pointer P sur une zone de mémoire contenant la chaîne constante originale 'Hello world!' C'est équivalent à :

const TempString: array[0..12] of Char = 'Hello world!';
var P: PChar;
   ...
P := @TempString[0];

Vous pouvez aussi passer des constantes chaîne aux fonctions qui prennent des valeurs ou des paramètres const de type PChar ou PWideChar - par exemple StrUpper('Hello world!'). Comme avec les affectations à un PChar, le compilateur génère une copie terminée par null de la chaîne et donne à la fonction un pointeur sur cette copie. Vous pouvez, enfin, initialiser des constantes PChar ou PWideChar avec des littéraux chaîne, seuls ou dans un type structuré. Exemples :

const
  Message: PChar = 'Program terminated';
  Prompt: PChar = 'Enter values: ';
  Digits: array[0..9] of PChar =
    ('Zero', 'One', 'Two', 'Three', 'Four', 'Five',
     'Six', 'Seven', 'Eight', 'Nine');

Les tableaux de caractères basés sur zéro sont compatibles avec PChar et PWideChar. Quand vous utilisez un tableau de caractères à la place d'une valeur pointeur, le compilateur convertit le tableau en une constante pointeur dont la valeur correspond à l'adresse du premier élément du tableau. Par exemple :

var
  MyArray: array[0..32] of Char;
  MyPointer: PChar;
begin
  MyArray := 'Hello';
  MyPointer := MyArray;
  SomeProcedure(MyArray);
  SomeProcedure(MyPointer);
end;

Ce code appelle deux fois SomeProcedure avec la même valeur.

Un pointeur de caractère peut être indexé comme s'il était un tableau. Dans l'exemple précédent, MyPointer[0] renvoie H. L'index spécifie un décalage ajouté au pointeur avant qu'il ne soit déréférencé. (Pour les variables PWideChar, l'index est automatiquement multiplié par deux.) Donc, si P est un pointeur de caractère, P[0] est équivalent à P^ et spécifie le premier caractère du tableau, P[1] spécifie le second caractère du tableau, et ainsi de suite ; P[-1] spécifie le "caractère" immédiatement à gauche de P[0]. Le compilateur n'effectue pas de vérification des bornes sur ces index.

La fonction StrUpper illustre l'utilisation de l'indexation de pointeurs pour parcourir une chaîne terminée par null :

function StrUpper(Dest, Source: PChar; MaxLen: Integer): PChar;
var
  I: Integer;
begin
  I := 0;
  while (I < MaxLen) and (Source[I] <> #0) do
  begin
    Dest[I] := UpCase(Source[I]);
    Inc(I);
  end;
  Dest[I] := #0;
  Result := Dest;
end;

Mélange de chaînes Object Pascal et de chaînes terminées par null

Vous pouvez mélanger des chaînes (valeurs AnsiString et UnicodeString) et des chaînes terminées par null (valeurs PChar) dans les expressions et les affectations, et vous pouvez passer des valeurs PChar aux fonctions ou procédures qui prennent des paramètres de type chaîne. L'affectation S := P, où S est une variable chaîne et P une expression PChar, copie une chaîne terminée par null dans une chaîne.

Dans une opération binaire, si un opérande est une chaîne et l'autre un PChar, l'opérande PChar est converti en un UnicodeString.

Vous pouvez transtyper une valeur PChar en un UnicodeString. Cela est utile pour effectuer une opération chaîne sur deux valeurs PChar. Par exemple :

S := string(P1) + string(P2);

Vous pouvez aussi transtyper une chaîne UnicodeString ou AnsiString en une chaîne terminée par null. Les règles suivantes s'appliquent :

  • Si S est un UnicodeString, PChar(S) transtype S en une chaîne terminée par null
    MessageBox(0, PChar(Str1), PChar(Str2), MB_OK);
Utilisez PAnsiChar(S) si S est un AnsiString.
  • Vous pouvez aussi utiliser Pointer(S) pour transtyper une chaîne en un pointeur non typé. Mais si S est vide, le transtypage renvoie nil.
  • PChar(S) renvoie toujours un pointeur sur un bloc mémoire ; si S est vide, un pointeur sur #0 est renvoyé.
  • Quand vous transtypez une variable UnicodeString ou AnsiString en pointeur, le pointeur reste valide jusqu'à ce qu'une nouvelle valeur soit assignée à la variable ou que la variable sorte de la portée. Si vous transtypez n'importe quelle autre expression chaîne en pointeur, le pointeur n'est valide qu'à l'intérieur de l'instruction où le transtypage est effectué.
  • Quand vous transtypez une expression UnicodeString ou AnsiString en pointeur, le pointeur doit généralement être considéré en lecture seule. Vous pouvez utiliser sans risque le pointeur pour modifier la chaîne uniquement si les conditions suivantes sont respectées
    • L'expression transtypée est une variable UnicodeString ou AnsiString.
    • La chaîne n'est pas vide.
    • La chaîne est unique, c'est-à-dire que son compteur de références vaut un. Pour garantir que la chaîne est unique, appelez les procédures SetLength, SetString ou UniqueString.
    • La chaîne n'a pas été modifiée depuis le transtypage.
    • Les caractères modifiés se trouvent tous dans la chaîne. Faites attention à ne pas utiliser d'index hors intervalle sur le pointeur.

Les mêmes règles s'appliquent aux mélanges de valeurs WideString à des valeurs PWideChar.

Voir aussi