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ásElõ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éseMint 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év | Példaérték | 
| i, d | Integer | 1, 42, -10 | 
| c | Karakter | a, o, * | 
| s | Karakterlánc | sztring, példa | 
| l | Logikai | true, false | 
| b | Bináris | 01001, 0b1100 | 
| h, x | Hexadecimális | 1A, 0x23 | 
| o | Oktális | 045 12 | 
| n | Szám | 42, 0b010, 0xAC, 045 | 
| f | Lebegõpontos | 0.7, -99.5 | 
| g | IEE lebegõpontos | 0.7, -99.5, INFINITY, -INFINITY, NAN, NAN_E | 
| u | Felhasználó név/id | ZeRo, 1 | 
| q | NPC név/id | ShopBot, 13 | 
| r | Játékos név/id | ZeRo, 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ásokA 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álatraAz 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