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

Signaler
-
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
12 juillet 2020
-
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

Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
11
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
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.
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
11
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
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
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
12 juillet 2020
420
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.
Messages postés
3811
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
15 juin 2020
30
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 !
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
Messages postés
675
Date d'inscription
jeudi 17 avril 2008
Statut
Membre
Dernière intervention
19 février 2019
11
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
Messages postés
251
Date d'inscription
lundi 27 octobre 2003
Statut
Membre
Dernière intervention
19 juin 2020
5
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;
@+
Messages postés
3811
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
15 juin 2020
30
ç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;



salut cs_yanb :

10000 merci ça marche très bien .

merci aussi à dubois77 et cirec pour le supoort aussi .
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
12 juillet 2020
420
Merci de mettre la question résolue, avec le lien "Marquer comme résolu" sous le titre.