Compter un nombre sous un string d'un fichier texte [Résolu]

- - Dernière réponse : Whismeril
Messages postés
13979
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
- 25 oct. 2015 à 19:33
Bonjour,
J'ai un fichier texte dont , je cherche à compter le nombre sous PDP
Dans tout le fichier texte, j'ai fait une tentative mais elle affiche une erreur :

listindex out of bound (812)

Un petit example du texte est comme suit :


PROC PDP R0P
W 9 110

PBIT QS STATE CAP
18 SIP 50%
18 FID 90%
9 OFF OPEN 80%

PROC PDP R0P
K 3 112

PBIT Q STATE CAP
18 SIP OPEN 10%
34 FID 70%
33 OFF 80%

PROC PDP R0P
N 0 235

PBIT Q STATE CAP

PROC PDP ROP
N 10 110

PBIT Q STATE CAP
34 FID 70%


le code est le suivant:
  procedure TForm1.Button1Click(Sender: TObject);      
var
SL:TStringList;
i, idx, nr : Integer;
begin
SL:=TStringList.Create;
try
SL.LoadFromFile('C:\texte.txt');
nr:=0;
for i:=0 to SL.Count-1 do begin
if ( Length(Trim(SL[i])) = 0 )
or ( Pos('PROC PDP R0P', SL[i]) <> 0 )
or ( Pos('SIP', SL[i]) <> 0 )
or ( Pos('FID', SL[i]) <> 0 )
or ( Pos('OFF', SL[i]) <> 0 )
or ( Pos('PBIT Q STATE CAP', SL[i]) <> 0 )

then SL.Delete(i);

idx:=1;
while idx <= length(SL[i]) do begin
if SL[i][idx+1] = 'PDP ' then
Inc(nr);
Inc(idx);
end;
end;
finally
SL.Free;
end;
ShowMessage('count: '+IntToStr(nr));
end;
end.



merci pour votre support
Afficher la suite 

11 réponses

Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
10
0
Merci
Bonjour
essaye pour voir cette méthode :
var SL1,SL2: tstringlist
...
begin
SL1:=TStringList.Create;
SL2:=TStringList.Create;
try
SL1.LoadFromFile('C:\texte.txt');
nr:=0;
for i:=0 to SL1.Count-1 do begin
if ( Length(Trim(SL[i])) = 0 )
or ( Pos('PROC PDP R0P', SL1[i]) <> 0 )
or ( Pos('SIP', SL1[i]) <> 0 )
or ( Pos('FID', SL1[i]) <> 0 )
or ( Pos('OFF', SL1[i]) <> 0 )
or ( Pos('PBIT Q STATE CAP', SL1[i]) <> 0 )

then continue //SL.Delete(i);
else SL2.items.add(SL1[i]);


et regarde ce qui te reste dans SL2
Commenter la réponse de dubois77
0
Merci
salut:

j'ai fait une ptite modification mais j'ai eu le code d'erreur suivant:

listindex out of bound (7)



procedure TForm1.Button1Click(Sender: TObject);
var
SL,SL2:TStringList;
I, idx, nr : Integer;

begin
SL:=TStringList.Create;
SL2:=TStringList.Create;
try
SL.LoadFromFile('C:\texte.txt');
SL2.Delimiter := ' ';
nr:=0;
for i:=0 to SL.Count-1 do begin

if ( Length(Trim(SL[i])) = 0 )


or ( Pos('SIP', SL[i]) <> 0 )
or ( Pos('FID', SL[i]) <> 0 )
or ( Pos('OFF', SL[i]) <> 0 )
or ( Pos('PBIT Q STATE CAP', SL[i]) <> 0 )


then SL.Delete(i) ;

SL2.DelimitedText := SL[I];
SL2.Add(SL[I]);

idx:=1;
while idx <= length(SL2[I]) do begin
if SL2[I][idx] = 'PDP ' then
Inc(nr);
Inc(idx);

end;
end;
finally
SL.Free;
SL2.Free;
end;
ShowMessage('count: '+IntToStr(nr));
end;


end.



NB: merci pour votre aide et suggestions.
Commenter la réponse de dino34
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
10
0
Merci
Il ne faut pas dans la boucle for faire : then SL.Delete(i) ;

car vers la fin il n'y aura plus de ligne à lire d'ou l'erreur
essaye avec then continue
Commenter la réponse de dubois77
0
Merci
Salut:

j'essaye d'éliminer les lignes non utile de tel sorte il reste cette structure
Pour pouvoir faire l'affichage de la somme de PDP (9+3+0+10) =22


PROC PDP R0P
W 9 110
PROC PDP R0P
K 3 112
PROC PDP R0P
N 0 235
PROC PDP ROP
N 10 110


Donc l'instruction suivante doit être faite le premier :

then SL.Delete(i) ; .

merci
Commenter la réponse de dino34
Messages postés
13979
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319
0
Merci
Bonsoir,
Peut être qu'avec les regex tu pourrais extraire tes valeurs plus facilement.

Je ne fais pas de Delphi, mais en .Net avec regex, ça prendrait moins de 10 lignes.
Commenter la réponse de Whismeril
Messages postés
3809
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 septembre 2019
32
0
Merci
Salut,

si tu veux effacer des Items dans une boucle il faut commencer à l'index Count-1

  for i := SL.Count-1 downto 0 do begin    
    if ...
    then SL.Delete(i) ; 
  end;          

et il n'y aura jamais de dépassement d'index avec ce code même si tous les Items sont supprimés !! ;)

petit plus ... il serait préférable d'encadrer le code par
BeginUpdate & EndUpdate;

  try
    SL.BeginUpdate;
    for i := SL.Count-1 downto 0 do begin
      if ...
      then SL.Delete(i) ;
    end;
  finally
    SL.EndUpdate;
  end;

l'exécution du code sera plus rapide ... surtout si le fichier est gros !
Commenter la réponse de Cirec
0
Merci
salut:

J'ai fait les modifications dans le code, mais j'obtiens toujours l'erreur suivante:

listindex out of bound (18)



try
SL.BeginUpdate;
for i := SL.Count-1 downto 0 do begin
if ...
then SL.Delete(i) ;
ShowMessage( SL.Text );
end;
finally
SL.EndUpdate;
end;


NB: un simple teste en ajoutant ShowMessage( SL.Text );

Les lignes de texte entré n'ont pas été effacées.

est ce que quelqu'un à une idée ?

merci
Commenter la réponse de dino34
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
10
0
Merci
Tu ne m'as pas répondu à ce message :
{
dubois77 17 oct. 2015 à 15:15
Il ne faut pas dans la boucle for faire : then SL.Delete(i) ;

car vers la fin il n'y aura plus de ligne à lire d'ou l'erreur
essaye avec then continue
}
essaie sans faire le delete et affiche ce qu'il y a dans SL2
Commenter la réponse de dubois77
Messages postés
248
Date d'inscription
lundi 27 octobre 2003
Statut
Membre
Dernière intervention
4 mars 2016
5
0
Merci
Salut,
au plus simple à adapter...
var
Src : TStringList;
Pdp : TStringList;
Tot : TStringList;
I : Integer;
Val : Integer;
begin
Src := TStringList.Create;
Pdp := TStringList.Create;
Tot := TStringList.Create;
try
Tot.Delimiter := ' ';
Val := 0;
Src.LoadFromFile('C:\Texte.txt');
for I := 0 to Src.Count - 1 do
begin
if Pos('PDP',Src[I]) <> 0 then
begin
Pdp.Add(Src[I]);
Pdp.Add(Src[I+1]);
Tot.DelimitedText := Src[I+1];
Val := Val + StrToIntDef(Tot[1],0);
end;
end;
Pdp.Add(Format('Nombre Total PDP : %d',[Val]));
Pdp.SaveToFile('C:\PDP.txt');
ShowMessage(Format('Nombre Total PDP : %d',[Val]));
finally
Src.Free;
Pdp.Free;
Tot.Free;
end;
@+
Commenter la réponse de cs_yanb
Messages postés
3809
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 septembre 2019
32
0
Merci
ça fonctionne très bien !!

1 TButton
1 TMemo pour voir le résultat et :
procedure TForm1.Button1Click(Sender: TObject);
var
  SL : TStringList;
  I: Integer;
begin
  SL := TStringList.Create;
  try
    SL.Delimiter := ';';
    SL.DelimitedText := '"PROC	PDP	R0P";"W	9	110";"PROC	PDP	R0P";"K	3	112";"PROC	PDP	R0P";"N	0	235";"PROC	PDP	R0P";"N	10	110"';
    try
      Memo1.Lines.AddStrings(SL);
      Memo1.Lines.Add('******************* Resultat ****************************');
      SL.BeginUpdate;
      for I := SL.Count - 1 downto 0 do
        if  Pos('R0P', SL[I])>0 then
          SL.Delete(I);
    finally
      SL.EndUpdate;
      Memo1.Lines.AddStrings(SL);
    end;
  finally
    SL.Free;
  end;
end;



Commenter la réponse de Cirec
0
Merci
salut cs_yanb :

10000 merci ça marche très bien .

merci aussi à dubois77 et cirec pour le supoort aussi .
Whismeril
Messages postés
13979
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319 -
Merci de mettre la question résolue, avec le lien "Marquer comme résolu" sous le titre.
Commenter la réponse de dino34