Selectionner une partie de caractères afin de les mettre dans un string

Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006 - 17 mai 2006 à 15:36
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006 - 18 mai 2006 à 09:18
Bonjour,


Je code une application et me trouve face à un probleme:

je possède une chaine de caractère contenant des caractères ascii ( ESCAPE ( 27 en ascii) ainsi que des signes, des lettres....

je souhaiterais "sortir" de cette string une string allant du premier caractère ESCAPE trouvé, jusqu'au prochain caractère ESCAPE rencontré ( il y en a plusieurs dans ma string).

j'ai déja fais un alogorythme permettant de trouver le premier caractère escape ( en indexant un i et en testant caractère a caractère pour tout ma chaine( Encore merci à ceux du forum ! :) ).

Le but serais de concatenner tous mes caractère se trouvant entre ces deux escape.( et cerise sur le gateaux, le premier escape suivi de tout ce qui suis, jusqu'au prochain ESC ( mais sans celui-ci))

je voudrais juste savoir comment concatenner plusieurs char en un string dans ce cas la!


Voila, mon probleme peut paraitre fastidieux, jai essayer de m'expliquer au plus clair ! Encore merci à toux ceux présente sur ce forum d'autant plus que je ne code en delphi que depuis 3 jours !!!

Bonne journée

TanK

18 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
17 mai 2006 à 15:50
uses StrUtils;

function CountChar(const S : string; const CharToCount : char) : integer;
var N : integer;
begin
  result := 0;
  N      := Posex(CharToCount,S,1);
  while N <> 0 do begin
    inc(result);
    N := Posex(CharToCount,S,N+1);
  end;
end;

function GetStrPart(const Str, Delimiter: String; const WordIndex: cardinal = 1): String;
var I,P1,P2 : integer;
begin
  Result := '';
  if (posex(Delimiter,Str[1]) = 1) and (WordIndex <= 1) then exit;
  P1 := 1;
  for I := 1 to WordIndex-1 do begin
      P1 := posex(Delimiter, Str, P1);
      if P1 = 0 then exit
      else P1 := P1 + length(Delimiter);
  end;
  P2 := posex(Delimiter, Str, P1);
  if P2 = 0 then P2 := length(Str) + 1;
  Result := copy(Str, P1, P2 - P1);
end;






a utiliser comme cela :

var
  List : TStringList;
  N    : integer;
begin
  List := TStringList.Create;
  for N := 1 to CountChar(Texte, #27)+1 do
      List.Add( GetStrPart(Texte, #27, N) );
end;

et si on veux concatener toute les chaine séparée :

function ReplaceChar(const S : string; const OldChar,NewChar : char) : string;
var  pS, pR : PChar;
begin
  Result := '';
  SetLength(Result, length(S));
  pS := PChar(S);
  pR := PChar(Result);
  While pS^ <> #0 do begin
    if pS[0] <> OldChar then
       pR[0] := pS[0]
    else
       pR[0] := NewChar;
    Inc(pR);
    Inc(pS);
  end;
end;

a utiliser comme suis :

var
  S : string;
begin
  S := ReplaceChar(Texte, #27, #32); // remplace Echape par Espace
end;
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
17 mai 2006 à 16:05
Salut,
où encore comme ceci :

Procedure ExtractText(Separateur, Ligne: String; Var aList : TStringList);
Var TmpText         : String;
Begin
  If aList = Nil Then Exit;
  While Pos(Separateur, Ligne) > 0 Do
    Begin
      TmpText : = Copy(Ligne, 1, Pos(Separateur, Ligne) - 1);
      If TmpText <> EmptyStr Then aList.Add(TmpText);
      Ligne := Copy(Ligne, Pos(Separateur, Ligne) + 1, High(Integer));
    End ;
  If Ligne <> EmptyStr Then aList.Add(Ligne);
End;


Utilisation :
procedure TForm1.Button1Click(Sender: TObject);
Var aList : TStringList;
begin
  aList : = TStringList.Create;
  ExtractText(#27, 'Le forum de CodeS'+#27+ 'SourceS à changé', aList);
  Memo1.Lines.Clear;
  Memo1.Lines.AddStrings(aList);
  aList.Free;
end;














@+
Cirec
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
17 mai 2006 à 16:15
Merci pour ta réponse très complete !!

il y a quand même quelquechose que je ne comprend pas, n'y a t-il pas plus simple en passant par une seule fonction qui irais concatener les char entre mes deux égales.

Prenont le cas ou ma valeur "I" est une valeur déja arrété sur un ESC

faire ainsi quelquechose du style;

for i to (nouvelle rencontre caractere ESC)

{
lecture de tous les caractères ( ESC,char1,char2,char3-->jusqu'a ESC)
afin d'en ressortir une string contenant dans cette exemple mon caractère ESCCHAR1CHAR2CHAR3 ( tout cela concatené évidement comme il me faut une string)

Encore merci à f0xi, mais je ne comprend pas trop ce code étant nouveaux en delphi, j'éspère avoir été plus explicite !

Encore merci à tous !!
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
17 mai 2006 à 16:39
Cirec, si j'ai bien compris, ta procedure Extract Text a pour but d'extraire du texte en y posant des limites, exactement ce que je cherche !! Mais ce ne serais pas plutot une fonction? afin d'avoir un retour du typoe string non ? (tmpText dans notre cas ?)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
17 mai 2006 à 16:52
Salut,

Alors oui on aurai pu en faire une fonction mais le problème est le suivant :
si on utilise une fonction il faut alors créer un Objet TStringList qui ne sera pas libéré après l'exécution de la fonction,
donc plusieurs appel à cette fonction provoquerai des fuites de mémoire.

C'est pour cette raison que j'ai opté pour une procédure :




Procedure ExtractText(Separateur, Ligne: String;Var aList : TStringList);

aList sert d'objet de sortie
Utilisation :
procedure TForm1.Button1Click(Sender: TObject);
VaraList : TStringList;
begin
  aList := TStringList.Create;  // l'objet est créer ici puis utilisé
  ExtractText(#27, 'Le forum de CodeS'+#27+ 'SourceS à changé', aList );
  Memo1.Lines.Clear;
  Memo1.Lines.AddStrings(aList);
  aList .Free;  // et enfin il est liberé ici
end;

Voilà en esperant que ce soit plus claire pour toi maintenant.
Sinon n'hésite pas à demander.

@+
Cirec
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
17 mai 2006 à 16:54
J'y vais de la mienne ?

function ExtractSubString(const S: string; const Ch: Char = #27): string ;
begin
  Result : = Copy(S, Pos(Ch, S) + 1, Length(S) - Pos(Ch, S));
  Result := Copy(Result, 1, Pos(Ch, Result) - 1);
end;

Bonne prog'
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
17 mai 2006 à 17:01
Salut Japee,

Alors oui, si tu veux extraire qu'une seule occurence, mais si il y en a plusieurs
d'ou le choix de la StringList

et en plus la procédure que je propose est polyvalente :

Comme Separateur on peut y mettre un Char (#27) où un mot ('le') etc.

@+
Cirec
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
17 mai 2006 à 17:02
Ahhh d'accord Cirec, je suis désolé, étant nouveaux dans l'orienté objet, je n'est pas encore les reflexe, je n'avais pas pensé au retour objet :d !
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
17 mai 2006 à 17:02
Ta solution est attrayante Japee !! Pourrais tu me la décrire si cela ne te dérange pas biensur !!
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
17 mai 2006 à 17:07
Salut les gars,

Désolé Tank01 j'ai pas le temps pour l'instant.
Mais comme le précise Cirec, je ne traite là qu'une seule chaîne.
A plus...

japee
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
17 mai 2006 à 17:16
Bien compris pour l'objet cirec, mais si il est détruit en fin de procedure, comment récupérer la string résultante, dans le "main" de mon programme ( désolé pour la "main", habitude de codeur en C++ )

Je souhaitais également savoir quelquechose, si j'ai bien compris, dans l'exemple que tu prend, on aura juste "Le forum de CodeS", or dans mon cas, la ligne peu contenir

ESCxbhbcdsb_-xjkxsqkj3457sdjh3(zad ESCsvffvdssd

je voudrais au final avoir une string egale à: ESCxbhbcdsb_-xjkxsqkj3457sdjh3(zad

ce que je veux dire, c'est que je ne sais pas à l'avance ce que ma qtring contiendra !

Encore désolé pour mes re-question a chaquefois, je suis conscient que ca n'est pas si simple que ca y parais et vous remerci pour votre patience à tous !

Note: Jai déja su faire un algo me detectant un ESC dans la string ( il parcour caractère à caractère jusqu'a tomber sur un #27)

voici mon code si il peu vous aider:

procedure TForm1.search_ESC_and_decrypte(string_to_test:string;char_to_search:string);
var Trouve:Boolean;
var i:integer;
var sequence_esc:string;
begin
Trouve:=False;
for i:=1 to Length(string_to_test) do
if string_to_test[i]=char_to_search then Trouve:=True;
if Trouve=true then //on a trouvé un esc, donc ,
begin
for i:=i to string_to_test[i]=#27 do //pour délimiter la séquence ESCAPE
begin
sequence_esc:=string_to_test[i]+string_to_test[i+1];

end;
canvas.Font.height:=20;
canvas.Font.Name:='roman';
canvas.TextOut(50,ClientHeight-100,sequence_esc);//----> On tente d'aficher la sequence ESC



end;


end;

Et oui, mon code est très bancale comme vous le voyez !!!
0
Utilisateur anonyme
17 mai 2006 à 19:28
Salut,

Tu devrais écrire des noms de procedures moins longues : rien que quand tu vas l'utiliser ulterieurement ca t'arrangera de ne pas etre obliger d'écrire un tel roman lol.

Deuxièmement :
procedure TForm1.search_ESC_and_decrypte(string_to_test:string;char_to_search:string)
à remplacer par
procedure TForm1.search_ESC_and_decrypte(string_to_test,char_to_search:string);


Voila A+
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
17 mai 2006 à 22:35
moi j'ai trouver la parade a ce genre de nom de methode a ralonge :

JustDoIt([args]);

simple et efficace et sponsorisé par Nike.

tiens on devrais traduire la RTL avec ce genre de principe de super identifiant de la mort a ralonge qui tue t'es a la bourre vas te laver tu veux un bisou y'a plus de papier tant pis.

aller just for fun :

Begin   : Begin_Of_Code_Declaration
End     : End_Of_Code_Declaration
Inc     : Addition_A_with_B_Or_One_If_B_Not_Defined
Dec     : Substract_A_by_B_Or_One_If_B_Not_Defined
Time    : Get_HNSZ_Time_Of_System_Clock
Date    : Get_YMD_Date_And_HNSZ_Time_Of_System_Clock
Now     : Get_The_Same_Thing_That_
Get_YMD_Date_And_HNSZ_Time_Of_System_Clock
TEdit   : TBox_Where_You_Can_Write_Short_Text
TButton : TRectangle_Where_You_Can_Push_With_Your_Mouse_Cursor
TForm   : TRectangle_Where_The_Magic_Operate_Or_Where_You_Can_Fly_Your_Excrements
TScrollBar : TFucking_Slider_That_You_Can_Slide_But_With_No_Control_Implemented
TTrackBar  : TFucking_Slider_Where_You_Have_No_Chances_To_Make_Thing_Properly
TMediaPlayer : TMicrosoft_Fucking_API_With_Congratulation_You_Are_Dead_Messages
TSpeedButton : TButton_When_The_Coder_Is_Drunk
TMemo : TBox_Where_You_Can_Create_A_NotePad_With_Microsoft_Look

vous imaginez le 'tudieu' de 'bordille' de 'coudel' ?

galere ce serait je dis!

en yoda plus simple parler serait.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
17 mai 2006 à 23:48
On a échappé au pire,
heureusement que les Dev de chez Borland nous ont épargnés ce genre de déclaclarations
quoi que le TSpeedButton m'a bien fait rire (encore une fois)


 


@ Tank01:

"Bien compris pour l'objet cirec, mais si il est détruit en fin de procedure, comment récupérer la string résultante, dans le "main" de mon programme ( désolé pour la "main", habitude de codeur en C++ )"
Pour une accèssibilité dans tout le "Main" il te faut dans ce cas tu déclare ta StringList juste après le mot réservé IMPLEMENTATION

Ex.:
Var
  Form1 : TForm1;
  // et si la liste doit être accèssible dans d'autres unités alors tu la déclares ici (avant l'implémentation)
Implementation
Var aList : TStringList;

// Dans l'inspecteur d'objet Onglet évènements (de la Form "Main") tu double-cliques sur OnCreate puis sur OnClose
// et tu les complètes comme suit
Procedure TForm1.FormCreate(Sender: TObject);
Begin
    aList := TStringList.Create; // ici on la crée
End;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Begin
    aList.Free;  // et ici on la libère
End;

"Je souhaitais également savoir quelquechose, si j'ai bien compris, dans l'exemple que tu prend, on aura juste "Le forum de CodeS", or dans mon cas, la ligne peu contenir"

Alors non l'exemple que je donne te donne le texte complet sans les #27
C'est le code de Japee qui te donne que la première partie

@+
Cirec
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
18 mai 2006 à 00:03
Ma modeste contribution :

TRadioButton : A_Pretty_Little_Hole_You_Can_Put_A_Point_In_The_Middle_Of_It
TCheckBox : Completely_Squared_Hole_You_Can_Put_A_Cross_Inside_Or_Not_ItsYourProblem
TLabel : IfItsFromCadiz_She_Got_Velvet_Eyes
TMemo : I_Dont_Remember
TListBox : HoHo___I_Have_Forgotten_To_Buy_LitiereForTheCat____Shit
TPanel : Its_Very_Representative_OfCourse
TShape : O_Melon_And_Leather_Boots
TImage : You_See_What_I_Mean___
TAnimate : Some_Breast_I_Presume
TUpDown : SomeTimesImUp_SomeTimesImDown_Because_Im_ManiacoDepressive
TToolBar : If_I_Had_An_Hammer___
TTimer : Its_Time_I_Stop_____________

David I, if you want my mail for a big contrat, there is not problem, I can working for Borland when you want, I am not too much expensive, see you later, man...

[mailto:j@pee j@pee]
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
18 mai 2006 à 08:47
Question toute bete, dans mon cas, ne serais il pas plus simple d'indexé toute la ligne contenue dans mon document texte, dans un tableau de char.Ensuite recherché le premier ESC, marqué cette index tel i par exemple, en suite continuer la recherche jusqu'a trouver le deuxième ESC. Je pourrais ensuite savoir de quel indice à quel indice s'étend ma séquence ESC ( donc elle démarre d'un ESC, et vas jusqu'au prochain ESC, excluant ce dernier), et ensuite extraire cette intervale dans un string? j'y est pensé après longue réflexion cette nuit :d, ce ne serais pas plus simple ?? Encore merci pour vos aides !!!
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
18 mai 2006 à 09:13
Cette fonction me rend fou !!!!!!! lol
Je vais vous montré la fonction construite, en fait, la recher du premier ESC fonctionne, voici tout cela.( j'ai commenté le code)

procedure TForm1.search_ESC_and_decrypte(string_to_test,char_to_search:string);

var Trouve:Boolean; //boolean pour savoir si ESC trouuvé
var i:integer;
var sequence_esc:string;

begin

Trouve:=False;
for i:=1 to Length(string_to_test) do //je parcoure toute ma string.

begin

if string_to_test[i]=char_to_search then Trouve:=True; //si ESC trouvé
if Trouve=true then //on a trouvé un esc, donc ,

begin

//Et c'est ici que je bloque, je voudrais partir du i en cours ( donc de l'endroit ou j'ai trouvé mon ESC jusqu'au prochain ESC, et stocker tout cela dans une string (sequence_esc en l'occurence))

voila l'idée que j'avais eu ( enfin le début), mais delphi aparemment n'en veut pas :

for i to i:=char_to_test //(pour aller du i EN COURS (donc du premier ESC) jusqu'au prochain ESC rencontré)

//Apres reste a indexé tous ces caractères dans un string, en gros pas facil du tout !! :(
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
18 mai 2006 à 09:18
correction, for i to i=char_to_test (et non :=)
0
Rejoignez-nous