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

dino34 - 15 oct. 2015 à 20:51 - Dernière réponse : Whismeril 11525 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 21 mai 2018 Dernière intervention
- 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 

Votre réponse

12 réponses

dubois77 689 Messages postés jeudi 17 avril 2008Date d'inscription 9 mars 2018 Dernière intervention - 16 oct. 2015 à 07:57
0
Utile
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
Utile
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
dubois77 689 Messages postés jeudi 17 avril 2008Date d'inscription 9 mars 2018 Dernière intervention - 17 oct. 2015 à 15:15
0
Utile
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
Utile
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
Whismeril 11525 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 21 mai 2018 Dernière intervention - 17 oct. 2015 à 21:52
0
Utile
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
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 11 mai 2018 Dernière intervention - 19 oct. 2015 à 17:02
0
Utile
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
Utile
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
dubois77 689 Messages postés jeudi 17 avril 2008Date d'inscription 9 mars 2018 Dernière intervention - 21 oct. 2015 à 18:31
0
Utile
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
cs_yanb 260 Messages postés lundi 27 octobre 2003Date d'inscription 4 mars 2016 Dernière intervention - Modifié par cs_yanb le 22/10/2015 à 08:59
0
Utile
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
Cirec 4221 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 11 mai 2018 Dernière intervention - 22 oct. 2015 à 16:08
0
Utile
ç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
Utile
salut cs_yanb :

10000 merci ça marche très bien .

merci aussi à dubois77 et cirec pour le supoort aussi .
Whismeril 11525 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 21 mai 2018 Dernière intervention - 25 oct. 2015 à 19:33
Merci de mettre la question résolue, avec le lien "Marquer comme résolu" sous le titre.
Commenter la réponse de dino34

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.