Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

DELPHI : PROCEDURE SPLIT SIMILAIRE A LA FONCTION EPONYME EN VB


Information sur la source

Catégorie :Compression & Split Classé sous : SPLIT, STRING, TEXTE, CHAINE, CSV Niveau : Débutant Date de création : 11/02/2008 Date de mise à jour : 06/03/2009 15:13:10 Vu / téléchargé: 7 220 / 249

Note :
Aucune note

Commentaire sur cette source (14)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Découpe une chaîne délimitée en ses éléments pour remplir un tableau dynamique passé en paramètre. Un type formel doit être déclaré pour le tableau dynamique (cf. demo en pièce jointe). Par suite, cette source est utilisable à partir de la version 4 de Delphi.
 

Source

  • procedure Split(const Delimiter: char; DelimitedText: string; var StrArray: TStrArray);
  • var
  • i, j, l: cardinal;
  • k: byte;
  • begin
  • { Fill the dynamic array with the items of a text delimited }
  • if (DelimitedText=EmptyStr) then begin
  • SetLength(StrArray, 1);
  • StrArray[0]:=EmptyStr;
  • end else if (Delimiter=#0) then begin
  • SetLength(StrArray, 1);
  • StrArray[0]:=DelimitedText;
  • end else begin
  • l:=Length(DelimitedText);
  • if (Copy(DelimitedText, l, 1)<>Delimiter) then begin
  • DelimitedText:=DelimitedText + Delimiter;
  • l:=l+1;
  • end;
  • SetLength(StrArray, 256);
  • k:=0;j:=0;
  • for i:=1 to l do
  • if (DelimitedText[i]=Delimiter) then begin
  • inc(k);
  • strArray[k-1]:=Copy(DelimitedText, j+1, i-(j+1));
  • j:=i;
  • end;
  • SetLength(StrArray, k);
  • end;
  • end;
procedure Split(const Delimiter: char; DelimitedText: string; var StrArray: TStrArray);
var
  i, j, l: cardinal;
  k: byte;
begin
  { Fill the dynamic array with the items of a text delimited }
  if (DelimitedText=EmptyStr) then begin
    SetLength(StrArray, 1);
    StrArray[0]:=EmptyStr;
  end else if (Delimiter=#0) then begin
    SetLength(StrArray, 1);
    StrArray[0]:=DelimitedText;
  end else begin
    l:=Length(DelimitedText);
    if (Copy(DelimitedText, l, 1)<>Delimiter) then begin
      DelimitedText:=DelimitedText + Delimiter;
      l:=l+1;
    end;
    SetLength(StrArray, 256);
    k:=0;j:=0;
    for i:=1 to l do
      if (DelimitedText[i]=Delimiter) then begin
        inc(k);
        strArray[k-1]:=Copy(DelimitedText, j+1, i-(j+1));
        j:=i;
      end;
    SetLength(StrArray, k);
  end;
end;

Conclusion

Vous noterez qu'il n'a pas été nécessaire d'instancier un TStringList ou d'ajouter une quelconque dépendance pour écrire cette procédure.

Rappel : le compilateur Delphi assure une gestion évoluée des tableaux dynamiques. Avec un autre compilateur, il vous faudra vérifier la libération de la mémoire allouée au tableau dynamique.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

11 février 2008 11:39:32 :
Mise à jour : limitation de l'emploi de SetLength
11 février 2008 11:45:33 :
Erreur de manipulation
11 février 2008 12:08:28 :
Optimisation : une seule affectation de la longueur du texte.
11 février 2008 12:24:40 :
Mise à jour précédente erronée.
11 février 2008 15:52:52 :
longueur max = 256
12 février 2008 08:14:20 :
Correction description
12 février 2008 09:09:43 :
Ajout commentaire dans le code source
12 février 2008 13:27:36 :
Modification du titre
18 février 2008 14:41:46 :
Ajout du cas particulier où le caractère de délimitation n'a pas été défini (Delimiter=#0).
18 février 2008 14:45:40 :
Erreur de manip.
06 mars 2008 12:25:14 :
MAJ de la procédure setCursor
26 août 2008 12:04:05 :
Correction grammaticale
03 décembre 2008 16:52:22 :
Zip (sup. des fichiers inutiles)
10 décembre 2008 09:22:14 :
Catégorie
23 décembre 2008 11:09:29 :
Conclusion (allocution de mémoire)
23 décembre 2008 12:00:30 :
Faute de frappe
23 décembre 2008 16:49:32 :
Conclusion
06 mars 2009 15:13:11 :
Correction : " for i:=1 to l do " au lieu de " for i:=0 to l do " L'index 0 d'un string comprend sa longueur ! Curieux... personne n'a relevé l'erreur certes sans incidence fonctionnelle.

Commentaires et avis

signaler à un administrateur
Commentaire de FENETRES le 11/02/2008 10:57:20

L'utilisation de SetLength limite la longueur du tableau à 255 éléments. "NewLength doit avoir une valeur comprise entre 0 et 255".

signaler à un administrateur
Commentaire de FENETRES le 11/02/2008 11:27:12

Par suite, il est possible de réduite l'emploi de setLength en déclarant d'abord la longueur maximum (255) puis la longueur effective trouvée (k).

signaler à un administrateur
Commentaire de FENETRES le 11/02/2008 15:55:50

Erratum :
   la longueur maximum du tableau dynamique est naturellement de 256 éléments.

signaler à un administrateur
Commentaire de pascal99 le 12/02/2008 10:28:47

Bonjour,
si mes souvenirs de VB sont bons, split est une fonction et delimiter une string (il peut etre compose de plusieurs caracteres) dont la valeur par defaut est l'espace.

Ce serait bien de modifier votre procedure en fonction.

Bons codes

signaler à un administrateur
Commentaire de FENETRES le 12/02/2008 11:08:55

Split(expression[, delimiter[, limit[, compare]]])

Alors, effectivement, vos souvenirs sont bons. Je n'ai pas le temps actuellement de surcharger cette méthode et d'écrire une procédure réellement semblable. Mais je vous promets de m'y atteler dès que possible.

signaler à un administrateur
Commentaire de FENETRES le 13/02/2008 14:51:59

La conversion de la procédure en fonction donnerait la signature suivante :

function Split(const Delimiter: char; DelimitedText: string): TStrArray;

Il n'y a donc pas de quoi fouetter un chat pas plus que l'élargissement du caractère de délimitation à un type string. L'ajout d'autres paramètres ne présente pas à mon point de vue un trés grand intérêt. C'est pourquoi, après réflexion et correction du titre, je ne  pense pas surcharger la méthode présentée.

Cordialement,

signaler à un administrateur
Commentaire de FENETRES le 05/03/2008 11:40:02

En aparté, vous pouvez notez la manière de récupérer un curseur système différent d'un curseur Delphi :

procedure TfrmDemo.frmDemoOnActivate(Sender: TObject);
  procedure setCursor(hWnd:integer; lpCursorName:PAnsiChar);
  var
    hCur:integer;
  begin
    try
      hCur:=LoadCursor(0, lpCursorName);
      SetClassLong(hWnd, GCL_HCURSOR, hCur);
    finally
      DestroyCursor(hCur);
    end;
  end;
begin
  //Déclare et affiche le caractère de délimitation
  Delimiter:=';';
  lblDelimiter.Caption:= 'Delimiter: "' + Delimiter + '"';
  //Curseur des boutons
  setCursor(btnSplit.Handle, IDC_HAND);
  setCursor(btnClose.Handle, IDC_HAND);
end;

signaler à un administrateur
Commentaire de Renfield le 05/03/2008 22:56:48 administrateur CS

    try
      hCur:=LoadCursor(0, lpCursorName);
      SetClassLong(hWnd, GCL_HCURSOR, hCur);
    finally
      DestroyCursor(hCur);
    end;

.... je codes en VB, pas en Delphi, mais... je trouve étrange de constater, à la leccture de ce code, que les API semblent générer des exceptions....

signaler à un administrateur
Commentaire de FENETRES le 06/03/2008 09:42:14

Bonjour l'artiste,

   Je ne comprends pas ta remarque car cette procédure ne génère aucune exception (Delphi7 ou 2007). D'ailleurs, il s'agit d'une transcription en Pascal d'une proc. très connue par les programmeurs VB. Il faudrait détailler le contexte et son usage.

signaler à un administrateur
Commentaire de Renfield le 06/03/2008 09:47:35 administrateur CS

je parle du try finally
est-ce réellement indiqué ici, dans la mesure ou tu ne fait qu'utiliser des APIs

au pire, elles renverront des codes indiquant une erreur...


enfin, y'a pas lieu de s'attarder là, j'ai juste vu passer ce commentaire sur la source, ca m'a intrigué.

signaler à un administrateur
Commentaire de FENETRES le 06/03/2008 09:56:02

Le "finally" est toujours exécuté même si une exception est levée. Dans ce cas, effectivement, il n'est pas vraiment nécessaire.

A+,

signaler à un administrateur
Commentaire de FENETRES le 06/03/2008 10:21:05

Pour information des lecteurs, voici les spécifications complètes de l'API qui a fait l'objet de la remarque fondée de notre ami Renfield.

Declaration:
Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorName As String) As Long

Parameters:
· hInstance
Identifies an instance of the module whose executable file contains the cursor to be loaded.

· lpCursorName
Points to a null-terminated string that contains the name of the cursor resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can also be used to create this value.
To use one of the Win32 predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the following values:
IDC_APPSTARTING
Standard arrow and small hourglass
IDC_ARROW
Standard arrow
IDC_CROSS
Crosshair
IDC_IBEAM
Text I-beam
IDC_ICON
Obsolete for applications marked version 4.0 or later.
IDC_NO
Slashed circle
IDC_SIZE
Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL.
IDC_SIZEALL
Four-pointed arrow
IDC_SIZENESW
Double-pointed arrow pointing northeast and southwest
IDC_SIZENS
Double-pointed arrow pointing north and south
IDC_SIZENWSE
Double-pointed arrow pointing northwest and southeast
IDC_SIZEWE
Double-pointed arrow pointing west and east
IDC_UPARROW
Vertical arrow
IDC_WAIT
Hourglass

Return values :
If the function succeeds, the return value is the handle of the newly loaded cursor.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.




signaler à un administrateur
Commentaire de FENETRES le 06/03/2008 11:51:09

Note : les déclarations des l'API utilisées se trouve dans l'unité Windows.

signaler à un administrateur
Commentaire de FENETRES le 06/03/2008 12:08:56


Procédure revue et corrigée (toute exception sera silencieuse).

procedure TfrmDemo.frmDemoOnActivate(Sender: TObject);
  procedure setCursor(hWnd:integer; lpCursorName:PAnsiChar);
  var
    hCur:integer;
  begin
    hCur:=LoadCursor(0, lpCursorName);
    if (hcur<>0) then begin
      SetClassLong(hWnd, GCL_HCURSOR, hCur);
      DestroyCursor(hCur);
    end;
  end;
begin
  //Déclare et affiche le caractère de délimitation
  Delimiter:=';';
  lblDelimiter.Caption:= 'Delimiter: "' + Delimiter + '"';
  //Curseur des boutons
  setCursor(btnSplit.Handle, IDC_HAND);
  setCursor(btnClose.Handle, IDC_HAND);
end;

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Enlever les accents d'un texte etc... [ par lomig ] Bonjour, je suis à la recherche d'un algo me permettant de transformerune chaine de caractere afin d'en enlever les eventuelles erreurs.Imaginons une longueur d'une chaine de texte (Len en VB) [ par Saeko ] comment connaitre la longueur d'une chaîne de texte ? y a-t-il un équivalent Delphi à l'instruction 'Len' de VB ?Merci d'avanceSaeko String et Retour chariot [ par lomig ] J'ai une chaine de caractere constituée de deux mots que je veuxséparer par un retour chariot et ensuite insérer cette chaine dans unfichier texte. Si remerciements [ par BRIVE ] Votre texte ICIVotre texte ICIBONJOURPour DELPHIPROGBien vu.Dans mon record la longueur du string n'était pas précisée.Lors de la lecture par seek,cel Integer et string [ par Programmeur1987 ] Bonjour j'aimerais savoir si il y a moyen d'intégrer un integer dans une chaine de string.Example dans mon cas :VarChangePass : Integer;beginChangePas Renverser une chaine de caractère [ par AMokers ] Salut à tous !Voila je voudrais renverser une chaine de caractere, j'ai trouver ce script :function InverseStr(sDep : string) : string;varsFin : strin conversion bit en string [ par biloue ] BonjourDans un programme je récupère une chaine de bit qui m'est envoyé par liaison UDP. Chaine composée de 0 et de 1.Je souhaiterai convertir cette c Executer du code texte [ par Niki2001 ] Est-il possible d'ex&#233;cuter du texte (sous forme de string) qui, &#233;videmment, repr&#233;senterait un code Delphi correct? Exemple:var&nbsp;&nb Remplacement de caractères pour chaques lettres [ par tony1239456 ] Bonjour, je voudrais savoir si il existe une fonction permettant de remplacer des caract&#232;res dans une chaine diff&#233;rents pour chaques lettres Formatage d'un string [ par titiyo ] bonjoursen fait jai un chaine de 10 espace et je veut rentre dedant toto sans augenter la taille de ma chaine resulta qui a comme longeur 10:chaine1 :


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,374 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.