Listbox - out of bounds

1

Listbox - out of bounds

offline
  • chuten 
  • Novi MyCity građanin
  • Pridružio: 22 Okt 2006
  • Poruke: 7

Poz Smile

Mucim se vec nekoliko sati ne mogu da resim ovaj problem
Program proverava svaku liniju iz listbox-a i proverava da li sadrzi string 'ABC', ako sadrzi brise liniju na kojoj se nalazi taj string.
medjutim na kraju mi javlja "EStringListError with message List index out of bounds"

Kako da resim ovo?
For I:=0 To Form1.ListBox1.Items.Count - 1 Do     begin        s := ListBox1.Items.Strings[i];         showmessage(s);         for j := 1 to length(S) do           if Pos('ABC', s) <> 0 then             begin             ListBox1.Items.Delete(i);           Break;         end;     end;
Hvala unapred na odgovoru.



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Pridružio: 15 Maj 2006
  • Poruke: 333
  • Gde živiš: Babušnica

For I:=ListBox1.Items.Count - 1 DownTo 0 Do     begin         s := ListBox1.Items.Strings[i];         showmessage(s);         if Pos('abc', s) <> 0 then ListBox1.Items.Delete(i);     end; end;

Druga for petlja ti ne treba. Dovoljna ti je samo Pos funkcija.



offline
  • chuten 
  • Novi MyCity građanin
  • Pridružio: 22 Okt 2006
  • Poruke: 7

Hvala puno!

offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

Losa je praksa raditi brisanje u For petlji.
Pogledaj sledecu While petlju.

var   i: integer; begin   i := 0   while i < ListBox1.Items.Count do   begin     if Pos('ABC', ListBox1.Items[i]) > 0 then ListBox1.Items.Delete(i)     else inc(i);   end; end

offline
  • savkic 
  • Novi MyCity građanin
  • Pridružio: 05 Jun 2007
  • Poruke: 29

> Program proverava svaku liniju iz listbox-a i proverava da li sadrzi string > 'ABC', ako sadrzi brise liniju na kojoj se nalazi taj string.

Kod brisanja petlja treba da ide unazad, dakle:

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

offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

savkic ::> Program proverava svaku liniju iz listbox-a i proverava da li sadrzi string > 'ABC', ako sadrzi brise liniju na kojoj se nalazi taj string.

Kod brisanja petlja treba da ide unazad, dakle:

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


Za badava sam izgleda napisao prethodnu poruku.

Ovo sa brojanjem unazad jeste logicno, ali je nepravilno.
Ako ikada budete napravili aplikaciju u kojoj istom objektu mogu da pristupe vise funkcija istovremeno, onda takvo brojanje pada u vodu jer samo na pocetku petlje proveravate koliko Itema ima u ListBoxu.
Moja petlja to proverava svaki put pre nego sto uradi krug petlje, tako da su manje opasnosti od gresaka ukoliko nesto drugo u medjuvremenu obrise ili doda nesto u ListBox.

offline
  • savkic 
  • Novi MyCity građanin
  • Pridružio: 05 Jun 2007
  • Poruke: 29

> Ovo sa brojanjem unazad jeste logicno, ali je nepravilno.
> Ako ikada budete napravili aplikaciju u kojoj istom objektu mogu da
> pristupe vise funkcija istovremeno, onda takvo brojanje pada u
> vodu jer samo na pocetku petlje proveravate koliko Itema
> ima u ListBoxu.

Pa sad, ako će više njih da koristi istovremeno listbox to može raditi iz glavnog threada ili iz više threadova. U prvom slučaju to znači da se iz jedne metode u toku petlje poziva neka druga koja manipuliše listom što sugeriše na problem u organizaciji koda. Ako će se to raditi iz više threadova najpre će imati problema sa thread sinhronizacijom jer VCL nije thread safe. Ako je potrebna nezavisna lista multithread lista onda treba koristiti TThradList. Za dato pitanje i dati problem sa ListBoxom kretanje unazad je najefikasnije rešenje.

offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

Nemam nesto volje za raspravljanje...
Neka bude da si u pravu (a ove moje godine iskustva u programiranju bacimo u vodu), s tim sto ovo uopste nema veze sa tim sto VCL nije thread safe. Bilo kojoj VCL komponenti mozes pristupiti iz Threada ako to radis pravilno (Synchronize, Critical sections itd.).

offline
  • savkic 
  • Novi MyCity građanin
  • Pridružio: 05 Jun 2007
  • Poruke: 29

Brisanje stavki unazad je prirodno i najbolje rešenje za TList i sve slične klase (gde spada i TStringList), uostalom tako i sam TList radi.
Ako petlja koja briše poziva ujedno i metodu koja dodaje nove stavke to je najverovatnije greška u dizajnu i tu nema rešenja koje će stavke obrisati u jednom prolazu (može ponavljanjem petlje).
Svejedno je da li se koristi for i := 0 to Count - 1;
for i := Count - 1 downto 0 ili
while Count - 1.
Naprosto metoda koja stavke dodaje to može učiniti na kraj, na početak, u sredinu ili proizvoljno mesto i ni jedna petlja to ne može na opšti način predvideti.

offline
  • Pridružio: 04 Sep 2003
  • Poruke: 24135
  • Gde živiš: Wien

Ja pricam o petlji koja brise, a u medjuvremenu neki drugi event obrise neki Item iz liste, pa time smanji broj Itema u listi, pa tvoja petlja ode opet u Index out of bounds jer je velicinu liste proverila samo jednom na pocetku petlje.

Anyway, rekoh vec da nemam volje da se raspravljam.
Priznajem da je tvoja metoda barem milion puta bolja od moje.

Ko je trenutno na forumu
 

Ukupno su 833 korisnika na forumu :: 48 registrovanih, 11 sakrivenih i 774 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: A.R.Chafee.Jr., amonsrb, bojcistv, bokisha253, cifra, Dannyboy, darios, deLacy, Dimitrije Paunovic, dulleo, Fabius, Faki-Valjevo, FOX, GenZee, grenadir, hologram, HrcAk47, ikan, ILGromovnik, Istman, Kaplar2, Karla, kunktator, laurusri, Lieutenant, Maschinekalibar, milenko crazy north, Miškić, nemkea71, nick79, oldtimer, opt1, Parker, pera12345, Posetilac1, proka89, raptorsi, Rogan33, sasa87, sasakrajina, Smajser, Stoilkovic, vargas, vathra, virked, VJ, vlad4, yrraf