Szerző Téma: [Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]  (Megtekintve 23395 alkalommal)

Nem elérhető ZeRo

  • 4620
  • Ex Globális Moderátor
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Dátum: 2010. Április 15. - 18:40:26 »
+7
A sscanf függvény
 
Mi is ez?
A sscanf függvény segítségével karakterláncokat bonthatunk szét megadott egységek szerint. Hasonlít a strtok függvényre, de sokkal gyorsabb, egyszerûbb, és sokoldalúbb is.
Telepítés / üzembehozás
Elõször is töltsük le a plugint innen, majd a szervermappád/plugins mappába másold be a sscanf.dll-t. Ezután nyisd meg a server.cfg-t, és a plugins sorhoz add hozzá a sscanf-ot így:
 
plugins sscanf

 

plugins sscanf.so

 
Most helyezzük el a sscanf2.inc-t a szervermappánk/pawno/include mappában. Ezek után nyissuk meg a Pawno-t, és ágyazzuk be a fejállományt:
[pawn]#include < sscanf2 >[/pawn]
És már használhatjuk is a függvényt!
Megjegyzés: Ha a forrásodban a sscanf valamelyik régebbi verzióját használtad, akkor töröld ki, mivel a fordító nem fogja átfordítani a kódodat!
Mûködése
Mint már fentebb említettem, megadhatjuk, hogy az általunk kiválasztott sztringet milyen formátum( ok )ba darabolja szét. Ez sokkal egyszerûbb, mint amilyennek hangzik.  ;) Lássunk egy példát!
[pawn]
public OnFilterScriptInit(  ) {
    //Tárolók létrehozása
    new szStr[ 12 ];
    new iNum;
    //A karakterlánc szétválasztása, és a darabok elhelyezése a megfelelõ tárolókban
    sscanf( \"Sscanf 2\", \"s[12]i\", szStr, iNum );
    print( szStr );
    printf( \"%i\", iNum );
    return;
}
[/pawn]
Az alábbi eljárást lefuttatva ezt az eredményt kapjuk:
 

Sscanf
2

 
Fontos észrevennünk, hogy így a részek a megadott formátumba kerülnek át a sztring formátum helyett( kivétel ha sztring formátumba választjuk szét, akkor ugyanaz marad természetesen ).
Lehetséges elválasztók:
Jelölés                      NévPéldaérték
i, dInteger1, 42, -10
cKaraktera, o, *
sKarakterláncsztring, példa
lLogikaitrue, false
bBináris01001, 0b1100
h, xHexadecimális1A, 0x23
oOktális045 12
nSzám42, 0b010, 0xAC, 045
fLebegõpontos0.7, -99.5
gIEE lebegõpontos0.7, -99.5, INFINITY, -INFINITY, NAN, NAN_E
uFelhasználó név/id                      ZeRo, 1
qNPC név/idShopBot, 13
rJátékos név/idZeRo, 33
Az \'átmentés\' módszere:
Íme egy rossz példa:
[pawn]sscanf( \"ez sscanf 2\", s[12]i, string, integer );[/pawn]
Ugyanis a fenti példában a \'sscanf\' karakterlánc( sztring ) típusú, de az elválasztásban mi az i betût használtuk, ami egész számot( integert ) kellene jelöljön. Ezt kiküszöbölhetjük az átmentés módszerével, aminek a jele a \\\\( mivel a sima \\ a fordítóprogram által már használatban van ). Tehát, az elõzõ példánk helyesen így nézne ki:
[pawn]sscanf( \"ez\\\\ sscanf 2\", s[12]i, string, integer );[/pawn]
Ha a string, és az integer nevû változók létre lennének hozva, és lefuttatnánk a fenti kódot, akkor az eredményünk a következõ lenne:
 

ez sscanf //Ez a \'string\' karakterlánc értéke
2 //Ez az \'integer\' változó értéke

 
Enumerációs elválasztás:
A sscanf egyik elõnye( például a strtok-al szemben ), hogy lehetõségünk van az adatokat egybõl egy felsorolt adattípusba( Enum ) rendezni. Ennek az elválasztásnak a jelölése egy \'e\' betûvel kezdõdik, ami az enumerációs elválasztást jelöli, egy \'<\' jellel folytatódik, ami az enumerációs elválasztás kezdetét jelöli, majd az elválasztók után egy \'>\' jellel végzõdik, ami pedig a folyamat végét jelöli. Egy példa:
[pawn]
//Globális névtérben létrehozunk egy felsorolt adattípust
enum eTest {
    szString[ 32 ],
    Float: fFloat,
    iInteger
}
new eData[ eTest ];
//És valahol hivatkozunk rá, mégpedig egy sztringbõl bemásoljuk az adatokat a megfelelõ helyekre
sscanf( \"Unformat 3.141593 2010\", \"e<s[32]fi>\", eData );
[/pawn]
Ezzel feltöltöttük értékekkel az eData vektort. De például, ha rossz sorrendben hivatkozunk rá, akkor hibaüzenetet fogunk kapni.
[pawn]sscanf( \"2010 Unformat 3.141593\", \"e<s[32]fi>\", eData);[/pawn]
Mivel a 2010 nem karakterlánc, az \'Unformat\' nem lebegõpontos érték, és a 3.141593 pedig nem egész típusú szám.
Ez a kis funkciója a függvénynek hasznos lehet például nagyobb játékmódoknál, vagy játékos-adatokat kezelõ rendszereknél, vagy bárhol máshol, ahol felsorolt adattípussal dolgozunk.
A \'kihagyás\' módszere:
A kihagyás lényege az, hogy a megadott részt beolvassuk a sztringbõl( bármilyen formátumú is az ), és ellenõrizzük( tehát feltétellel ki lehet szûrni, ha rossz a bevitt érték ), de a különbség az a sima elválasztással szemben, hogy itt a kihagyott rész nem kerül mentésre, tehát nem kell megadnunk változót a visszatérési értéknek.
A jele a \'{\', illetve a \'}\' karakterek, ami egyértelmûen a kihagyás kezdetét, és végét jelölik. Az alábbi példában az elsõ értéket kezeljük a kihagyással:
[pawn]sscanf( \"6 47\", {i}i, integer );[/pawn]
Amint fent is említettem, két értéket, és két elválasztó karaktert láthatunk, de csak egy visszatérési változót, aminek oka - amint már leírtam - az, hogy a kihagyással kezelt érték nem kerül mentésre, tehát a kód folytatása során nem tudunk rá hivatkozni.
Így a fenti példában az \'integer\' nevû változónk értéke 47 lesz, a 6 pedig törlõdik( elvetõdik ). És amint azt az elején leírtam, a bevitt adatok ugyanúgy ellenõrzésre kerülnek, tehát a következõ kód hibát eredményezne:
[pawn]
new integer;
if( sscanf( \"kettõ 2\", {i}i, integer ) )
[/pawn]
Mivel a \'kettõ\' sztring típusú, de mi integer típusú elválasztót rendeltünk hozzá( ugyan kihagyás van, de ezt nem zárja ki ).
Ezt a módszert akárhányszor alkalmazhatjuk az elválasztásaink során, amikor csak szükségünk van rá. Ezenkívül az enumerációs elválasztásokba is beágyazhatjuk õket, nem lesz rá hatással.
[pawn]sscanf( \"7 3.14 kutya 42 INFINITY x\", \"e<ifs[12]{ig}c>\", enumData );[/pawn]
Karakteres elválasztások
A függvénnyel lehetõségünk van továbbá karakterek által elválasztott adatok szétválasztására is. Nézzünk egy egyszerû példát!
[pawn]sscanf( \"1,2,3\", \"p<,>iii\", num1, num2, num3 );[/pawn]
A fenti kódrészletben a sztringet a megadott karakter mentén( itt a , mentén ) elválasztottuk, és integer típusú változókba helyeztük. Alakja egyszerû: a p jelenti a karakteres elválasztást, a < az elválasztás kezdetét, a benne lévõ karakter( itt a VESSZÕ ) az elválasztási karaktert, a > pedig az elválasztás végét( szerkezete majdnem megegyezik az enumerációs elválasztáséval ).
Ez a módszer természetesen mûködik az enumerációs elválasztásban is, és ez az egyetlen eset, ahol két <> van egymásba ágyazva. Egy példa:
[pawn]
//Létrehozunk egy enumerációs egységet
enum e_Data {
    int,
    Float: ffloat,
    string[ 24 ]
}
//Valahol hivatkozunk rá, mondjuk egy parancsban
new e_Var[ e_Data ];
sscanf( \"12432 3.14,ZeRo\", \"e<ip<,>fs[24]>\", e_Var );
[/pawn]
Ha csak karakterláncokkal használjuk ezt a módszert, akkor a mûvelet viselkedése kicsit módosul, ugyanis a legtöbb elválasztó érzékeny a szóközre. Ez azt jelenti, hogy például ez mûködni fog, annak ellenére, hogy nincs benne \';\' karakter:
[pawn]sscanf( \"1 2 3\", \"p<;>iii\", var0, var1, var2 );[/pawn]
De ez nem minden esetben mûködik. Példa egy kivételre:
[pawn]sscanf( \"hello 1\", \"p<->s[32]i\", str, var );[/pawn]
Itt ugyanis a str változó értéke hello 1 lesz. És végül zárjunk egy helyes példával:
[pawn]sscanf( \"hello there>27\", \"p<>>s[32]i\", str, var );[/pawn]
Ez mûködni fog, és a következõ eredményt adja vissza:
 

hello there
27

 
Példa egy parancsban való használatra
Az alábbi parancsban megmutatom, hogy mennyivel egyszerûbb kezelni ezt az egészet a sscanf-al, mint mondjuk a strtok-al. Nézzünk egy /pm parancsot!
[pawn]
CMD:pm( playerid, params[  ] ) {
    //Tároló létrehozása az azonosítónak, és az üzenetnek
    new iPid;
    new szMsg[ 100 ];
    if( sscanf( params, \"is[100]\", iPid, szMsg ) ) {
        SendClientMessage( playerid, COLOR_RED, \"Használat: /pm < JátékosID > < Üzenet >\" );
    } else if( !IsPlayerConnected( iPid ) || IsPlayerNPC( iPid ) ) {
        SendClientMessage( playerid, COLOR_RED, \"Érvénytelen azonosító!\" );
    } else {
        new szStr[ 128 ];
        format( szStr, sizeof szStr, \"[ PM ]: %s( %i ): %s\", GetPlayerNameEx( playerid ), playerid, szMsg );
        SendClientMessage( iPid, COLOR_YELLOW, szStr );
    }
    return 1;
}
GetPlayerNameEx( playerid ) {
    new z[ MAX_PLAYER_NAME ];
    GetPlayerName( playerid, z, sizeof z );
    return z;
}
[/pawn]
Megjegyzés:
A függvényt lehetõségünk van unformat néven is használni. Ezt az alternatív megoldást azért hozta létre Y_Less, hogy elkerülje a félreértéseket ezzel, és a C nyelv beli sscanf függvénnyel kapcsolatban.




Utolsó frissítés: 2011/05/09
« Utoljára szerkesztve: 2011. November 08. - 17:18:24 írta ZeRo »

[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #1 Dátum: 2010. Április 15. - 18:59:28 »
0
Nagyon szépen köszönöm :shy: és végre értem :) már csak majd be is kell tanulni és gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni :D

Nem elérhető ZeRo

  • 4620
  • Ex Globális Moderátor
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #2 Dátum: 2010. Április 15. - 19:18:16 »
0
Idézetet írta: Vampesz date=1271350768\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"1375\" data-ipsquote-contentclass=\"forums_Topic
Nagyon szépen köszönöm :shy: és végre értem :) már csak majd be is kell tanulni és gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni-gyakorolni :D
 
Örülök ha tényleg sikerült egy új módszert( jobb módszert ) mutatnom.  ;) Amint már írtam, még bovítve lesz ez a leírás, majd jelzem itt, hozzászólásban.

Nem elérhető Csabesz

  • 7827
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #3 Dátum: 2010. Április 15. - 19:25:14 »
0
Jó lett. Szépen leírtad.  ;)

Nem elérhető Depi

  • 2259
  • Még mindig TrYp. :)
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #4 Dátum: 2010. Április 15. - 19:35:38 »
0
Szép munka barátom,grat,habár egy kis \"Tutoriált\" már nekem tartóttál ebbol + a zcmd-bol,de szép leírás grat  :)

Nem elérhető ZeRo

  • 4620
  • Ex Globális Moderátor
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #5 Dátum: 2010. Április 15. - 19:36:01 »
0
Kösz mindenkinek.  ;)

[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #6 Dátum: 2010. Április 16. - 16:10:50 »
0
A sscanf?
Az* sscanf szerintem...én az unformat néven használnám
Egyébként nem rossz

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #7 Dátum: 2010. Április 17. - 10:14:53 »
0
Jó leírás grat! Már végre megfogom tanulni az ienek használatát. Ám majd vki írhatna is strtock al, hogy mivel nehezebb az xD

[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #8 Dátum: 2010. Április 17. - 10:22:39 »
0
Idézetet írta: kurta999 date=1271492093\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"1375\" data-ipsquote-contentclass=\"forums_Topic
Jó leírás grat! Már végre megfogom tanulni az ienek használatát. Ám majd vki írhatna is strtock al, hogy mivel nehezebb az xD
 
Az könnyebb szerintem de viszont eggyúttal lassabb is.

Nem elérhető jana4

  • 5929
  • Ex Staff
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #9 Dátum: 2010. Április 17. - 15:00:31 »
0
jó tut, grat! am az i (integer) mögé mér kell a [100] ?

Nem elérhető ZeRo

  • 4620
  • Ex Globális Moderátor
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #10 Dátum: 2010. Április 17. - 15:05:09 »
0
Idézetet írta: ScreaM date=1271509231\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"1375\" data-ipsquote-contentclass=\"forums_Topic
jó tut, grat! am az i (integer) mögé mér kell a [100] ?
 
Nem, egyedül a sztring típusú( s ) elválasztásoknál kell megadni a méretet.
Dicséreteket köszönöm.

[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #11 Dátum: 2010. Április 17. - 15:05:16 »
0
is[100]

 
integer és string[100]

ha erre gondoltál :)


E: ZeRo megelozött :) am ja végülis le lehet rövidíteni 1-2 dolgot :D

GroX

  • Vendég
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #12 Dátum: 2010. Április 18. - 15:30:42 »
0
Én eddig is ismertem, és valamennyire tudtam használni de ez segített kösz.
Ezt fogom használni innentol, de az admin scriptemet már nem írom át mert már sok parancsot írtam meg strtok-al.

Nem elérhető ZeRo

  • 4620
  • Ex Globális Moderátor
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #13 Dátum: 2010. Április 26. - 21:21:58 »
0
Enumerációs elválasztás hozzáadva( a példa fölött van ).

Nem elérhető kurta999

  • 2759
  • Éllő fédisznó
    • Profil megtekintése
[Scripting Eszköz]A sscanf függvény [Paraméter Beolvasó]
« Válasz #14 Dátum: 2010. Augusztus 04. - 22:38:22 »
0
Tom, h régi tut. De azt is hozzáadhatnád, hogy, h kell Alapértemezett értéket megadni vminek. ( Mert szerintem az elég sokan nemtudják. )
Meg még az { } -jel használatát is. ( Kihagyás )
« Utoljára szerkesztve: 2010. Augusztus 09. - 16:35:40 írta kurta999 »

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal