Petlja i bug

1

Petlja i bug

online
  • Pridružio: 14 Feb 2008
  • Poruke: 12391

Testiram neki kod i naleteo sam na bug koji se vratio ...

Da li ste ikada videli ovakvu petlju ?

var QCnt : int = 0; for (var i = 0; i <= linije.Length-1; i++){   test[QCnt].QID= parseInt(linije[i]); i++;   test[QCnt].QTXT= linije[i]; i++;     test[QCnt].A1TXT= linije[i]; i++;   test[QCnt].A2TXT= linije[i]; i++;   test[QCnt].A3TXT= linije[i]; i++;   test[QCnt].A4TXT= linije[i]; i++;   test[QCnt].C1= parseInt(linije[i]); i++;     test[QCnt].C2= parseInt(linije[i]); i++;   test[QCnt].C3= parseInt(linije[i]); i++;   test[QCnt].C4= parseInt(linije[i]);   QCnt++ ;   }

Da li vidite neki potencijalni problem sa tim kodom ili neku nelogičnost ?


Šta još treba da znate o kodu :

test je niz klase sačinjene od različitih tipova promenljivih - koji se mogu videti u kodu iznad (QID, QTXT, ID... )

Dakle test = ImeKlase[20]; Imeklase{ QID :int; QTXT : string; ... }

//
Test niz izgleda ovako ako sve bude ok :
test[0].QID = 23;
...
test[1].QID = 25;
...

//
Postoji jedan storage fajl sa istim formatom unosa :

23 [end] Test [end] Mycity forum [end] bla[end] ...

Ja delim taj storage fajl upotrebom .Split() u niz linije i zatim prolazim kroz ceo niz i brišem sve \n i \r charove.

Tako da taj niz na kraju dobije ovakav izgled :

linije[0] = 23
linije[1] = Test
linije[2] = MyCity forum
linije[3] = bla

I sada dolazimo do onog prvog koda gore, koji iz tog niza popunjava niz klase.

I šta je tu problem ?
Kod nekada perfektno radi, kod nekada ne radi uopšte, kod nekada radi ali dobijem grešku poput :
Array Index Out of Range ili da je unos u pogrešnom formatu kod parseInta ... Što nagoveštava da grešim negde sa i brojačem ali to nije istina jer i kada se pojavi greška sve radi perfektno... Dok ne dodam neki novi unos u storage fajlu.

Svi predlozi dobrodošli ... Very Happy



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Milan
  • Pridružio: 17 Dec 2007
  • Poruke: 14809
  • Gde živiš: Niš

Da li je broj linija uvek jednak proizvodu broja atributa i broja objekata koji se čitaju?

Inače, ovakav način pisanja petlji je uvek rizičan za "Array Index Out of Range" izuzetke. Zašto? Zato što se promenljiva i menja i u zaglavlju petlje, ali i u telu petlje, a koristi se kao indeks unutar petlje. Uzmi za primer da ti je linije.Length = 3. Tada je početni uslov za petlju zadovoljen, ali si ti već nakon trećeg inkrementiranja van dužine niza linije.



online
  • Pridružio: 14 Feb 2008
  • Poruke: 12391

Ovo je fiksna stvar.

Unosi su u istom formatu.
Jednu celinu čini 10 unosa/linija.
Svejedno prepravio sam kod malo i sada izgleda ovako :

var repeat: int = linije.Length - 1 / 10; Debug.Log("Repeat" + repeat); var i: int = 0; //for (var i = 0; i <= linije.Length-1; i++){ for (var b = 0; b <= repeat; b++) {     //Debug.Log ("cnt" + i);     if (i >= linije.Length - 1) {         break;     }     test[Qcnt].QID = parseInt(linije[i]);     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].QTXT = linije[i];     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].A1 = linije[i];     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].A2 = linije[i];     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].A3 = linije[i];     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].A4 = linije[i];     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].C1 = parseInt(linije[i]);     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].C2 = parseInt(linije[i]);     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].C3 = parseInt(linije[i]);     i++;     //Debug.Log ("cnt" + i);     test[Qcnt].C4 = parseInt(linije[i]);     i++;     Qcnt++;

Dakle sada prvo delim ceo niz sa 10, dobijam tačan broj celina.
Ponavljam petlju samo toliko puta a ona upisuje redom liniju po liniju u odgovarajući niz klase.
-1 zato što streamwriter ostavlja jednu liniju praznu na kraju fajla pa je lakše tako to rešiti nego čistiti tu jednu liniju.

Takođe sam prepravio kod koji upisuje u fajl i uklonio razmak ispred " [end]" jer sam imao čudne probleme sa formatiranjem.

I sada to lepo radi, testirao sam sa 6 celina tj. 60 unosa...



Ali izgleda da ovde nije kraj i da nema mnogo veze sa ovom petljom...

Čas isti kod radi, čas ne radi. Verujem da dolazi do drugih problema ispod haube samog endžina :/

Baš me izluđuje.

Ova izmena bi trebala da bude sigurnija od prethodne u svakom slučaju ...
U suštini ne interesuju me problemi ispod haube, bitno je da na kraju radi kada se iskompajlira.

No, moguće je da će i ovo bacati probleme sa novim unosima, probaću sutra da napravim ogromnu bazu i da testiram.

Ziveli

offline
  • PHP developer
  • Pridružio: 22 Mar 2006
  • Poruke: 3747
  • Gde živiš: 127.0.0.1

vasa.93 ::ovakav način pisanja petlji je uvek rizičan za "Array Index Out of Range" izuzetke

U ovom konkretnom slucaju "Array Index Out of Range" nije rizican, vec skoro siguran, osim ako duzina niza "linije" nije deljiva sa 10 bez ostatka.

Ja bih pre uradio ovako nesto:

//uvek izbaci kalkulacije van petlje var limit = Math.ceil(linije.length / 10); for (var i = 0; i < limit; i++){    var idx = (i - 1) * 10;    var tmp = {       QID     : typeof linije[idx]   !== "undefined" ? linije[idx]   : "n/a",       QTXT    : typeof linije[idx+1] !== "undefined" ? linije[idx+1] : "n/a",       A1TXT   : typeof linije[idx+2] !== "undefined" ? linije[idx+2] : "n/a",       A2TXT   : typeof linije[idx+3] !== "undefined" ? linije[idx+3] : "n/a",       A3TXT   : typeof linije[idx+4] !== "undefined" ? linije[idx+4] : "n/a",       A4TXT   : typeof linije[idx+5] !== "undefined" ? linije[idx+5] : "n/a",       C1      : typeof linije[idx+6] !== "undefined" ? linije[idx+6] : "n/a",       C2      : typeof linije[idx+7] !== "undefined" ? linije[idx+7] : "n/a",       C3      : typeof linije[idx+8] !== "undefined" ? linije[idx+8] : "n/a",       C4      : typeof linije[idx+9] !== "undefined" ? linije[idx+9] : "n/a",    };    test.push(tmp); }

uz napomenu da nemam pojma o kom se jeziku radi, ali da jako lici na javascript, pa sam u njemu napisao kod iznad.

offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

var repeat: int = linije.Length - 1 / 10;
Pazi ovde, deljenje ima prednost!

Da bi ti kod bio citljiviji i sigurniji prvo sto upises u fajl bi trebalo da bude sam broj unosa.
var count : int = parseInt(linije[0]); var test : ImeKlase [count]; for (var iUnos = 0; iUnos < count; ++iUnos) {     test[iUnos].QID = parseInt(linije[iUnos * 10 + 1 + 0]); // +1 zato sto preskacemo prvu liniju (broj unosa)     test[iUnos].QTXT = linije[iUnos * 10 + 1 + 1];     ...     test[iUnos].C4 = parseInt(linije[iUnos * 10 + 1 + 9]); }

Kad si vec korisito Debug.Log trebao si ispisivati sadrzaj instanci a ne kauntera (i) da bi bolje video sta se dogadja.

Mozda sam pogresio u sintaksi jer ne poznajem Unity javascript-like skript jezik.

offline
  • Milan
  • Pridružio: 17 Dec 2007
  • Poruke: 14809
  • Gde živiš: Niš

Napisano: 28 Sep 2014 11:12

Morando, zar umesto test[iUnos].QID = parseInt(linije[iUnos + 1 + 0]); ne bi trebalo da ide test[iUnos].QID = parseInt(linije[iUnos*10 + 1 + 0]); Question

U prvom prolazu iUnos je 0, pa se čitaju linije od 1 do 10, u drugom prolazu iUnos je 1, pa se čitaju linije od 2 do 11. Morao bi da se iUnos množi sa brojem atributa/linija koje se čitaju.

Dopuna: 28 Sep 2014 11:14

Rastafarii ::U ovom konkretnom slucaju "Array Index Out of Range" nije rizican, vec skoro siguran, osim ako duzina niza "linije" nije deljiva sa 10 bez ostatka.Upravo sam na to mislio kada sam upitao da li je broj linija jednak proizvodu broja atributa i broja objekata koji se čitaju. Obzirom da je broj atributa 10, broj linija mora da bude celobrojni umnožak broja 10, a to je broj koji je deljiv sa 10. Very Happy

offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

Da, puta deset, to sam zaboravio. Very Happy
Dodje mi komsija i dok smo pili kafu seti se toga ali ne stigoh da ispravim.

online
  • Pridružio: 14 Feb 2008
  • Poruke: 12391

Izvinite što kasnim sa odgovorom, nisam mogao pre da se dočepam kompa.

Javiću kasnije šta se izdešavalo sa mojim kodom i predlozima ovde.

Kao što rekoh, uvek je fiksno sve kada su unosi u pitanju tako da ima bar jedna celina od 10 linija...
Tako će uvek biti osim u slučaju kada neko čačne storage fajl nepravilno, pri čemu je sam kriv.

Morando, ne znam koliko bi meni bilo praktično da brišem i pišem tu liniju svaki put (broj unosa) zbog ograničenja Unityja sa editorom. Morao bih onda stalno da osvežavam inspektor ... Ovako sigurno znam koliko unosa ima kada podelim sve linije sa 10. Kontrolisano ih dodajem u storage fajl.

U pravu si naravno za deljenje, zaboravio zagrade jutros Very Happy

Takođe nije bitno u kom jeziku pišete, shvatiću poentu dok god nema u kodu nešto specifično samo za taj jezik.

Javim se večeras, tokom jutra ili sutra sa rezultatima Ziveli

offline
  • PHP developer
  • Pridružio: 22 Mar 2006
  • Poruke: 3747
  • Gde živiš: 127.0.0.1

Srki, a jesi li razmisljao da umesto plain-text storage fajla koristis JSON? Tako ti ne treba ovaj kod uopste Wink

online
  • Pridružio: 14 Feb 2008
  • Poruke: 12391

Rastafarii ::Srki, a jesi li razmisljao da umesto plain-text storage fajla koristis JSON? Tako ti ne treba ovaj kod uopste Wink

Nisam, niti sam siguran da li bi radilo to tako, Plugins folder se obično koristi u pro verziji Unityja.

Ovaj kod je OK za moje potrebe. Izvrši se samo jednom kada se učitava prvi put igra i traje tokom cele sesije. Nema nikakvih izmena dok radi igra već je sve fiksno i podesi se pre kompajliranja, uključujući redosled izvršavanja skripti, jer se ovo sastoji od bar 3 skripte. Ako sve radi pre kompajliranja u editoru radiće i u igri kasnije bez problema.

Inače, testirao sam sa 60 i 80 unosa kod koji sam drugi put postovao.
Sve radi savršeno i bio sam u pravu - postoji jedan problem ispod haube.

Kada se upišu nove vrednosti u storage fajl Unity ih ne pokupi uopšte i onda skripta nema iz čega da čita tj. kada pokuša da nađe ono što traži toga nema...

To je ipak drugi problem i nema veze sa ovom temom niti sa opštim programiranjem, moraću da pitam na Unity forumu zašto je to tako.

Sve u svemu izgleda da smo rešili problem Very Happy
Nadam se... tako sam mislio i prošli put pa se vratio posle mesec dana Smile

Hvala društvo, imate pivo na okupljanju ili šta god, sok od zove i to Mr. Green Zagrljaj

Ko je trenutno na forumu
 

Ukupno su 815 korisnika na forumu :: 42 registrovanih, 7 sakrivenih i 766 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: AK - 230, aleksmajstor, Apok, atmel, Atomski čoban, babaroga, Bokiboks, bokisha253, BraneS, bufanje, cavatina, dankisha, darios, draganca, Georgius, HrcAk47, ivan1973, Karla, krkalon, kybonacci, lucko1, mnn2, MrNo, Nobunaga, ozzy, Panter, Rogan33, royst33, Shinobi, Srki94, StepskiVuk, Sumadija34, Tas011, Toper, vathra, voja64, yrraf, YugoSlav, Zi0mek, Zikapk, zillbg, šumar bk2