[ t3chX @ 28.08.2002. 12:50 ] @
Evo pitanjca:

dakle imam main metod definisan kao


void main(int argc, char* argv[])

a pitanje je vezano za uporedjivanje argv[1] sa nekim stringom:

if(argv[1] == "nesto") {

...

}

Dakle, sve je ok, program prima argumente kada se pozove iz cm. linije, medjutim
ono sto me muci je da nece da uporedi ovo dvoje, odnosno hoce, ali ne izvrsava se kod unutar if bloka... Da li neko zna resenje, a da je nevezano za getopt_long() ?

Napominjem da sam probavao sledeci kod:

char* a[10];
char* b[10];

a[1] = "nesto";
b[1] = "nesto1";

if (a[1] == b[1])
cout << "Isti.";
else cout << "Nisu isti.";

i tu sve radi kako treba ... znaci pitanje je Zasto nece uporedjivanje kod argv-a ?
[ Ivan Dimkovic @ 28.08.2002. 12:58 ] @
Koristi strcmp()
[ Dejan Lozanovic @ 28.08.2002. 13:24 ] @
Citat:
t3chX:
Evo pitanjca:

dakle imam main metod definisan kao


void main(int argc, char* argv[])

a pitanje je vezano za uporedjivanje argv[1] sa nekim stringom:

if(argv[1] == "nesto") {

...

}

Dakle, sve je ok, program prima argumente kada se pozove iz cm. linije, medjutim
ono sto me muci je da nece da uporedi ovo dvoje, odnosno hoce, ali ne izvrsava se kod unutar if bloka... Da li neko zna resenje, a da je nevezano za getopt_long() ?

Napominjem da sam probavao sledeci kod:

char* a[10];
char* b[10];

a[1] = "nesto";
b[1] = "nesto1";

if (a[1] == b[1])
cout << "Isti.";
else cout << "Nisu isti.";

i tu sve radi kako treba ... znaci pitanje je Zasto nece uporedjivanje kod argv-a ?


A joj ti si pobrkao babe i zabe, vidi kod C-a a i C++ niz se vidi kao pokazivac na prvi clan niza tako da ako imas npr char a[10]; u programu a[5] znaci isto sto i *(a+5) tako da uporedjivanje dva stringa sto si naveo je u sustini uporedjivanje adresa na koja ta dva pointera pokazuju. Naravno ovo se mnogo razlikuje od semantike paskala ili Basica ili nekog treceg jezika. u sustini trebalo bi znak po znak da poredis unutar stringa sto u sustini radi strcmp funkcija. Ukoliko bi zeleo da stringove tako poredis trebalo bi da uradis neku klasu string i da definises operatore za poredjenje koji su ti potrebni.
[ t3chX @ 28.08.2002. 13:53 ] @
Uhm, ocekivao sam ovakve odgovore .. medjutim savetujem svima da uzmu ovaj kod prekopiraju ga i kompajliraju:

<tCX> #include <iostream>
<tCX> using namespace std;
<tCX> void main()
<tCX> {
<tCX> char* a[3];
<tCX> char* b[3];
<tCX>
<tCX> a[1] = "tcx";
<tCX> b[1] = "tcx";
<tCX>
<tCX> if(a[1] == b[1])
<tCX>
<tCX> cout << "isti";
<tCX> else cout << "nisu";
<tCX>
<tCX> }

uzmite i menjajte vrednosti a[1] i b[1] i recite mi sta dobijate. Nakon toga mi objasnite zasto i argv[1] ne mogu porediti sa '==' ...
[ Predrag Damnjanovic @ 28.08.2002. 14:11 ] @
if (strcmp(arg1, arg2)==0)
{
// isti
}
else
{
// nisu isti
}
[ Dragi Tata @ 28.08.2002. 17:17 ] @
Citat:
t3chX:
<tCX> char* a[3];
<tCX> char* b[3];
<tCX>
<tCX> a[1] = "tcx";
<tCX> b[1] = "tcx";
<tCX>


Nemoj mi samo reći da ti ovo radi?
[ Ivan Dimkovic @ 28.08.2002. 17:20 ] @
Mozda je neki super-inteligentan kompajler!
[ Predrag Damnjanovic @ 28.08.2002. 18:39 ] @
Izgleda da "tcx" konvertuje u broj pa na tu lokaciju postavi da pokazuje njegov pointer, a zatim alocira 4 bajta, smesti "tcx" i udari 0x00
[ Dejan Lozanovic @ 28.08.2002. 19:43 ] @
Eh sada dolazimo do onog drugog dela kako je smesten C program u memoriji, i sasvim je moguce da ce ti program raditi iako sam toga nisi svestan zasto radi. Naime svaki proces(program koji se izvrsava ) se satoji iz vise sekcija, na dnu se nalazi text sekcija, zatim nakon toga se nalazi inicializovane(konstante) promenjive, a iznad se nalaze neinicijalicovane promenjljive. Ostali deo memorije je podeljen na dva dela heap(dinamicki alocirana memorija) koji se "puni" sa doljnje strane i stack koji se "puni" sa gornje.

Za detaljnije oko svega ovoga procitaj clanak koji se bavi pisanjem exploita, za buferowerflow, ali su pre svega detaljno opisali gde i kako stoje stvari u memoriji.

A sada da se vratimo zasto je to jednako, pa pre svega "tcx" je jedna inicijalizovana bezimena promenljiva, sada sto se pojavila vise puta kompajler je bio pametan pa je vise "tcx" promenljivih smetio kao jednu te istu u vreme kompajliranja. naravno da "tcx1" ne prolazi kao jednaka sa "tcx" jer kompajler nije mogao da unifikuje "tcx" i "tcx1". Ujedno razlog zasto ti ne prolazi argv[1] jer je ona neinicijalizovana( ne\ije poznata njena vrednost u vreme izvrsavanja).

Opet ako si i dalje neverni toma, napisi jedan

Code:

printf("pokazivac a[1] okazuje na %p pokazivac b[1] pokazuje na %p\n",a[1],b[1]);


%p treba da ti da ti ispise adresu na koju pokazuje a[1] i b[1]. E sada ukoliko sve to probas na nekom UNIX-u iskoristi komandu size <izvrsni fajl> pa pogledaj sekciju data(konstante) i videces da u slucaju kada bi trebalo da koristis isti "tcx" biti manja za 5 bajtova nego u slucaju da b[1] pokazuje na "tcx1"

Jos malko teorije text i data su read only, tako da u slucaju da probas da uradis nesto oavko
Code:

a[1][1]='d';


dobices Seg. Fault.

Toliko o tome.
Pozdrav

PS Cela ova prica je neka vrste opste programerske kulture, tako da me cudi da su se moderatori "malko" obrukali :), no sve je za ljude
;)
[ Dragi Tata @ 28.08.2002. 20:40 ] @
Uh, prevideo sam "zvezdice". Učinilo mi se da pokušavaš da dodeliš string literal char promenljivoj.

Uglavnom, da uprostimo stvari. Ukoliko uradiš nešto kao

Code:


char* a = "tekst";
char* b = "tekst";

if (a == b)
  printf("jednaki");
else
  printf("razliciti");



ako je verovati Bjarne Stroustrup-u nedefinisano je da li će da se pojavi "jednaki" ili "različiti" - to zavisi od kompajlera. Neki kompajleri će "primetiti" da je string literal isti u oba slučaja i rezervisaće samo jedno mesto u memoriji za njega i u tom slučaju će se pojaviti "jednaki". Neki drugi kompajler će svaki string literal staviti u posebnu memorijsku lokaciju i onda će se pojaviti "različiti".

Uglavnom, zlatno pravilo glasi: kad upoređuješ sadržaj C stringova, zaboravi na operator == i koristi strcmp.

[Ovu poruku je menjao Dragi Tata dana 28.08.2002 u 11:47 AM GMT]
[ Dragi Tata @ 28.08.2002. 20:46 ] @
I još jedan savet. Pošto već koristiš C++, a ne C, batali char* i koristi std::string.
[ random @ 29.08.2002. 00:54 ] @
Citat:
Dragi Tata:
ako je verovati Bjarne Stroustrup-u nedefinisano je da li će da se pojavi "jednaki" ili "različiti" - to zavisi od kompajlera. Neki kompajleri će "primetiti" da je string literal isti u oba slučaja i rezervisaće samo jedno mesto u memoriji za njega i u tom slučaju će se pojaviti "jednaki". Neki drugi kompajler će svaki string literal staviti u posebnu memorijsku lokaciju i onda će se pojaviti "različiti".


Bravo Tata, to je suština, i objašnjava ono što je njega zbunilo.
[ leka @ 29.08.2002. 15:26 ] @

To sam mu i ja rekao na IRC-u Nemanja.

Citat:
Dragi Tata:
Uglavnom, zlatno pravilo glasi: kad upoređuješ sadržaj C stringova, zaboravi na operator == i koristi strcmp.