Compter un nombre sous un string d'un fichier texte

Résolu
dino34 - 15 oct. 2015 à 20:51
Whismeril
Messages postés
17470
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
29 juin 2022
- 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

11 réponses

dubois77
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
14
16 oct. 2015 à 07:57
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
0
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.
0
dubois77
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
14
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
0
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
0

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

Posez votre question
Whismeril
Messages postés
17470
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
29 juin 2022
599
17 oct. 2015 à 21:52
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.
0
Cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
48
19 oct. 2015 à 17:02
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 !
0
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
0
dubois77
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
14
21 oct. 2015 à 18:31
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
0
cs_yanb
Messages postés
267
Date d'inscription
lundi 27 octobre 2003
Statut
Membre
Dernière intervention
20 mai 2022
13
Modifié par cs_yanb le 22/10/2015 à 08:59
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;
@+
0
Cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
48
22 oct. 2015 à 16:08
ç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;



0
salut cs_yanb :

10000 merci ça marche très bien .

merci aussi à dubois77 et cirec pour le supoort aussi .
0
Whismeril
Messages postés
17470
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
29 juin 2022
599
25 oct. 2015 à 19:33
Merci de mettre la question résolue, avec le lien "Marquer comme résolu" sous le titre.
0