Szerző Téma: [Leírás]strtok (használata)  (Megtekintve 4607 alkalommal)

[Leírás]strtok (használata)
« Dátum: 2012. Április 22. - 19:40:39 »
+4
Tudom létezik több száz leírás de írok egyet én is.
Az strtok nem más mint egy karakterlánc feldarabolására használatos eljárás.
A kód:
 
stock strtok(const string[], &index)
{
new length = strlen(string);
while ((index < length) && (string[index] <= \' \'))
{
index++;
}
new offset = index;
new result[20];
while ((index < length) && (string[index] > \' \') && ((index - offset) < (sizeof(result) - 1)))
{
result[index - offset] = string[index];
index++;
}
result[index - offset] = EOS;
return result;
}

 
Használata eléggé egyszerû: (fontos megjegyezni hogy ezen verzió maximálisan 20 karakternyi karakterláncokra darabolja a bevitt adatainkat. (new result[20];)
Példaként egy parancsot használnék, legyen a parancsunk a:
 
/nem fogod használni 1 percet sem ezt a parancsot

 
Ha mi ezt beírnánk játék közben akkor ez visszahívásként megjelenne nekünk az OnPlayerCommandText cmdtext[] változójában.
 

public
OnPlayerCommandText(playerid, cmdtext[])
{
new
PlayerName[MAX_PLAYER_NAME];
GetPlayerName(playerid, PlayerName, sizeof PlayerName);
printf(\"(%d %s) - %s\", playerid, PlayerName, cmdtext);
return 1;
}

 
Miután játék közben beírtuk a parancsot, a fenti kód sorozat az azonosító számunkat(playerid) a játékosnevünket(PlayerName) és a beírt parancsunkat(cmdtext[]) kiírja konzolba és menti a server_log.txt fájlba, a következõképp:
 
(0 Zsolesszka) - /nem fogod használni 1 percet sem ezt a parancsot

 
Innen láthatjuk hogy a használt parancsot a cmdtext[] változó tárolja számunkra.
Nekünk ezt fel kell darabolni hogy feltudjuk használni minden egyes paraméterét külön, konzolban egymás alá kifogjuk íratni a parancsunk elemeit, erre használhatjuk az strtok függvényt de erre a célra több eljárás is létezik, a legismertebb és a legtöbbet használt Y_Less sscanf pluginja által biztosított sscanf( ) eljárás.
Azt tudjuk már hogy a cmdtext[] változó tárolja a parancsot.
Ezt kell nekünk strcmp-vel le ellenõriztetnünk. Amirõl még nem ejtettem szót az az hogy az strtok az a space karakter mentén darabolja parancsukat.
Ezt persze meg is lehet változtatni, de alap esetben és legtöbbet a space-t használjuk még ebben a leírásban is a szavak elválasztására használom.  :laugh:
Az strcmp-hez szokás legelsõnek feldaraboltatni strtok-kal minden bejövõ adatot amit a (cmdtext[]) tárol, mert ha nem tennénk, akkor a következõ ellenõrzést hajtaná végre, ami hamis eredményhez vezethet.
 
strcmp(cmdtext, \"/nem\", true)
strcmp(\"/nem fogod használni 1 percet sem ezt a parancsot\", \"/nem\", true)

 
A cmdtext tartalmát behelyettesítettem az strcmp-be és így láthatjuk hogy az összehasonlítás nem megfelelõ számunkra. Mert csak a legelsõ résszel kellene össze hasonlítást végeztetnünk.
 
public
OnPlayerCommandText(playerid, cmdtext[])
{
new
idx = 0,
str[20];
str = strtok(cmdtext, idx);
if(strcmp(str, \"/nem\", true) == 0)
//   if(strcmp(\"/nem\", \"/nem\", true) == 0)
{
return 1;
}
return 0;
}

 
Az strtok vissza tért nekünk a \"/nem\" karakterekkel és elmentette az (str[20];) változóba, miközben a (cmdtext[]) még mindíg tárolja számunkra a komplett parancsunkat. Így már az strcmp egyezést fog találni és megfelelõ eredményt ad vissza ami a program futását megfelelõ írányba engedi tovább.
Az idx változó pedig tárolja a space karakterek pozicióját számunkra. (az str változónak 20-as értéket adtam meg, mert felesleges nagyobb a példában, mert az strtok is 20 karakternyi értékkel tér vissza (new result[20];).
A parancsunk többi paraméterét az strtok többszöri használatával tudjuk feldaraboltatni, amit egy komplett példával szemléltetnék.
 
public
OnPlayerCommandText(playerid, cmdtext[])
{
//   cmdtext = \"/nem fogod használni 1 percet sem ezt a parancsot\";  // Ezt tartalmazza a cmdtext változó
new
idx = 0, // space karakter poziciójának tárolása
str[20]; // Az strtok által visszatért adat tárolása 20 karakternyi az strtok maximálisan annyival tér vissza ami elég szokott lenni (new result[20];)
str = strtok(cmdtext, idx); // strtok által visszatért adat str = \"/nem\"  idx = 4; (a \"/nem\" karakterlánc utáni space vagy null karakter \'\\0\' pozíciója)
if(strcmp(str, \"/nem\", true) == 0) // strcmp(\"/nem\", /nem\", true);
{
printf(\"%s idx: %d\", str, idx); // nem
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 4);
printf(\"%s idx: %d\", str, idx); // fogod
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 10);
printf(\"%s idx: %d\", str, idx); // használni
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 20);
printf(\"%s idx: %d\", str, idx); // 1
printf(\"strval: %d\", strval(str));  // 1
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 22);
printf(\"%s idx: %d\", str, idx); // percet
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 29);
printf(\"%s idx: %d\", str, idx); // sem
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 33);
printf(\"%s idx: %d\", str, idx); // ezt
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 37);
printf(\"%s idx: %d\", str, idx); // a
str = strtok(cmdtext, idx); // strtok-nak küldött adat: strtok(\"/nem fogod használni 1 percet sem ezt a parancsot\", 39);
printf(\"%s idx: %d\", str, idx); // parancsot
return 1;
}
return 0;
}

 
Ebbõl láthatjuk hogy az idx változónk a space karakterek pozicióját tárolja.
A pawn nyelv 0-tól számol sok mindent, ezért a per jelünk (/) a nulladik karakter.
/nem(4)fogod(10)használni(20)1(22)percet(29)sem(33)ezt(37)a(39)parancsot(49)
Remélem így már kicsit érthetõbb lesz  pár személynek, az strtok használata.
« Utoljára szerkesztve: 2012. Április 24. - 17:01:23 írta ɐʞzssǝlosz »

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Leírás]strtok (használata)
« Válasz #1 Dátum: 2012. Április 23. - 14:15:43 »
0
Szép leírás, nagyon könnyen meg lehet érteni.
Én már több, mind 3 éve scriptelek és még komolyabban a CNPC teszt scripten kívül máshol ezt nem használtam.
(Mivel kezdettõl sscanf-el kezdem, mert erre egy normális leírást sem találtam akkoriba :D)

[Leírás]strtok (használata)
« Válasz #2 Dátum: 2012. Április 23. - 16:56:39 »
0
Idézetet írta: kurta999 date=1335183343\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"20541\" data-ipsquote-contentclass=\"forums_Topic
Szép leírás, nagyon könnyen meg lehet érteni.
Én már több, mind 3 éve scriptelek és még komolyabban a CNPC teszt scripten kívül máshol ezt nem használtam.
(Mivel kezdettõl sscanf-el kezdem, mert erre egy normális leírást sem találtam akkoriba :D)
 
Kösz, igyekeztem érthetõre írni, amúgy én is sscanf-et használok, csak van pár publikált filterscript amibe nem akartam azt használni.
(felesleges egy két parancsért egy plugin (sscanf.dll/so), ha meg lehet oldani másképp)
Így 90 százalék az esély arra, hogy még 3-4 év múlva is mûködõképes a publikált script amiben csak strtok van használva sscanf plugin helyett.  ;D

Nem elérhető divkn

  • 3259
    • Profil megtekintése
[Leírás]strtok (használata)
« Válasz #3 Dátum: 2012. Április 23. - 23:13:44 »
0
Egyszerû funkció, de nagyszerû leírás! Csak egy apró észrevétel.
 
Idézetet írta: ɐʞzssǝlosz date=1335116439\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"20541\" data-ipsquote-contentclass=\"forums_Topic

//printf(\"(%d %s) - %s\", playerid, PlayerName, cmdtext);

 
Miután beírtuk a parancsot a fenti függvény az azonosító számunkat(playerid) a játékosnevünket(PlayerName) és a beírt parancsukat(cmdtext[]) kiírja konzolba és menti a server_log.txt fájlba, a következõképp:
 
0 Zsolesszka /nem fogod használni 1 percet sem ezt a parancsot

 

(0 Zsolesszka) - /nem fogod használni 1 percet sem ezt a parancsot

 
Nem nagy probléma, de ne zavarjuk össze a teljesen kezdõket.
« Utoljára szerkesztve: 2012. Április 23. - 23:14:39 írta divkn »

[Leírás]strtok (használata)
« Válasz #4 Dátum: 2012. Április 23. - 23:16:16 »
0
Kösz.
Javítva.
Edit:
És még pár elírás is javítva.  ::|
« Utoljára szerkesztve: 2012. Április 23. - 23:23:40 írta ɐʞzssǝlosz »

[Leírás]strtok (használata)
« Válasz #5 Dátum: 2012. Április 24. - 15:00:13 »
0
Szép leírás, de amúgy nem igazán értem mire gondoltál a \"több száz leírás\" alatt, én csak egy normálisabbra emlékszem ezen kívül, amit Y2K írt még régebben.
Amúgy pár helyen kicserélõdött 1-2 karakter hangulatjelekre, pl. ;) = ;)
 
;) = ;)

Nem elérhető tonyo

  • 1335
  • Moderális Generátor
    • Profil megtekintése
[Leírás]strtok (használata)
« Válasz #6 Dátum: 2012. Április 24. - 16:17:49 »
0
Szép, érthetõ, igényes leírás =)
 
[...]van pár publikált filterscript amibe nem akartam azt használni.
(felesleges egy két parancsért egy plugin (sscanf.dll/so), ha meg lehet oldani másképp)
Így 90 százalék az esély arra, hogy még 3-4 év múlva is mûködõképes a publikált script amiben csak strtok van használva sscanf plugin helyett. 
[/quote]
Bár én elég régóta használom, de örülök, hogy végre más is úgy látja, hogy nem felesleges dolog azért, ha még \"manapság\" is tudjuk hogy mûködik. Sokszor olyan filterscriptekben, melyben van 1 parancs, használnak sscanf-ot... Holott, az sscanf-nak csak a plugin verziója gyorsabb a strtok-nál...(legalább is régebben így volt)


Azért kíváncsi lennék egy strtok plugin mennyivel lenne gyorsabb az sscanf-nál...
« Utoljára szerkesztve: 2012. Április 24. - 16:19:30 írta Anthony »

Nem elérhető Norby

  • 1575
    • Profil megtekintése
[Leírás]strtok (használata)
« Válasz #7 Dátum: 2012. Április 24. - 16:29:17 »
0
Szép értelmesen meg van fogalmazva én is úgy tanultam a pawn nyelvet hogy sscanf al daraboltam...
De így most már tudom alkalmazni ezt is én teljesen meg értettem amit írtál.
Egy kis hiba : parancsukat.
Ez nem \"parancsunkat.\" lett volna ? :)

[Leírás]strtok (használata)
« Válasz #8 Dátum: 2012. Április 24. - 17:17:22 »
0
Köszönöm, említett helyesírási hiba javítva és a hangulatjel gond is.
Az strtok + (strval, floatstr) egyetlen egy integer vagy float típusú plusz paraméternél gyorsabb mint a sscanf plugin.
 
pl.:
használat : /wheater [index]
/wheater 12
A parancs megírásához strtok, strval használata javasolt.
 
[/quote]
A sscanf plugin gyorsasága a sokkal több információval rendelkezõ karakterláncok (parancsok) darabolásában mutatkozik meg.
 
pl.:
használat: /car [vehiclename/modelid] [color1] [color2]
/car infernus 124 234
A parancs megírásához sscanf plugin használata javasolt.
 
[/quote]

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal