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
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
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.
Jó lett. Szépen leírtad. ;)
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 :)
Kösz mindenkinek. ;)
A sscanf?
Az* sscanf szerintem...én az unformat néven használnám
Egyébként nem rossz
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
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.
jó tut, grat! am az i (integer) mögé mér kell a [100] ?
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.
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
É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.
Enumerációs elválasztás hozzáadva( a példa fölött van ).
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 )
1-2 hónapja használom, és meg vagyok vele elégedve! A tutorial pedig lényegretörõ.
Az átmentés, és a kihagyás módszereket hozzáadtam. Valamikor várható még frissítés, tudom, hogy az elõzõ már régen volt, de most kedvet kaptam hozzá, így megcsináltam. Akinek kérdése van, az nyugodtan tegye fel, nem számít topikbumpolásnak.
Az a kérdésem, régebben volt velem ilyen, hogy létrehoztam egy \'/hp\' parancsot, meg egy \'/lecsuk\' parancsot. Eddig minden rendben, de amikor megpróbálok valakinek életpontot adni, akkor a \'lecsukás\' jön be. Ez miért van? [\'Használat: /lecsuk [iD]\']
Ez nem lehet sscanf probléma, inkább helytelen visszatérés lehet az oka. Ha bemásolod a kódrészletet, akkor tudok segíteni.
jó tut bár engem már chucknoris megtanitott erre viszont az elválasztokra volt szükségem köszike!!
Remek kiegészítés ZeRo, ha tudnálak karmázni, adtam volna egy + -t :)
Kapott tõlem.
Kösz nektek. :angel:
Még van egy módszer amit használni szoktak/szoktam, az pedig, ha a változó típusok valamilyen karakterrel el vannak választva. Pl:
asd|1.0|krisk|15
Ezt a következõképp tudjuk SSCANF-fal szétválasztani:
new str[]=\"asd|1.0|krisk|15\";
new string[4];
new Float:lebeg;
new nev[MAX_PLAYER_NAME];
new integer;
sscanf( str,\"p<|>sfui\",string,lebeg,nev,integer );
A két <> közti karakter az a karakter, amivel a típusokat elválasztottad.
Még van egy módszer amit használni szoktak/szoktam, az pedig, ha a változó típusok valamilyen karakterrel el vannak választva. Pl:
asd|1.0|krisk|15
Ezt a következõképp tudjuk SSCANF-fal szétválasztani:
new str[]=\"asd|1.0|krisk|15\";
new string[4];
new Float:lebeg;
new nev[MAX_PLAYER_NAME];
new integer;
sscanf( str,\"p<|>sfui\",string,lebeg,nev,integer );
A két <> közti karakter az a karakter, amivel a típusokat elválasztottad.
Ezt én a MySql regisztrációnál beolvasásra használom,tényleg hasznos.
Különben nagyon jó a leírás ZeRo. :)
Én is arra használom amúgy. :D mysql_fetch_row()-val közérakom, ezzel meg szétszedem.
Hát.. mivel azt mondtad, h \"maradi\" a gondolkodásmódom, ki akartam próbálni 0.3c RC5 alatt.
De sajnos b4szik betölteni a plugint, szoval ennyit errõl az egész sscanf dologról ^^
[12:30:37] Server Plugins
[12:30:37] --------------
[12:30:37] Loading plugin: sscanf
[12:30:37] Failed.
[12:30:37] Loaded 0 plugins.
[/quote]
Nálam mindig betöltõdik.
Szedd le ezt: http://www.y-less.com/YSI/sscanf.zip
[13:18:10] Loading plugin: sscanf
[13:18:10]
[13:18:10] ===============================
[13:18:10] sscanf plugin loaded.
[13:18:10] © 2009 Alex \"Y_Less\" Cole
[13:18:10] ===============================
[13:18:10] Loaded.
[13:18:10] Loaded 2 plugins.
[/quote]
Mostse tölti be XD
linux vagy windows?
windows.
Plugins mappába tedd be a plugint és server.cfgben:
plugins sscanf2
Így csináltad?
próbáltam sscanf, meg sscanf2-vel is
kattints a herére
te meg nyald meg ^^
amugy kösz, fentvan.
Van kód formájában is,használd azt,ezerszer jobb mint a strtok,
Van kód formájában is,használd azt,ezerszer jobb mint a strtok,
Ez igaz, viszont a pluginos verzió ~10x gyorsabb a simánál, szóval azt kellene mûködésre bírnia. :)
te meg nyald meg ^^
amugy kösz, fentvan.
Akk próbáld meg az összes elõzõt is felrakni..
Inkább a kód, de azt sehol nem találtam.
Valaki lnikelje :D
Inkább a kód, de azt sehol nem találtam.
Valaki lnikelje :D
Nekem még megvan a régi:
stock sscanf(string[], format[], {Float,_}:...) // By Alex \"Y_Less\" Cole
{
#if defined isnull
if (isnull(string))
#else
if (string[0] == 0 || (string[0] == 1 && string[1] == 0))
#endif
{
return format[0];
}
#pragma tabsize 4
new
formatPos = 0,
stringPos = 0,
paramPos = 2,
paramCount = numargs(),
delim = \' \';
while (string[stringPos] && string[stringPos] <= \' \')
{
stringPos++;
}
while (paramPos < paramCount && string[stringPos])
{
switch (format[formatPos++])
{
case \'\\0\':
{
return 0;
}
case \'i\', \'d\':
{
new
neg = 1,
num = 0,
ch = string[stringPos];
if (ch == \'-\')
{
neg = -1;
ch = string[++stringPos];
}
do
{
stringPos++;
if (\'0\' <= ch <= \'9\')
{
num = (num * 10) + (ch - \'0\');
}
else
{
return -1;
}
}
while ((ch = string[stringPos]) > \' \' && ch != delim);
setarg(paramPos, 0, num * neg);
}
case \'h\', \'x\':
{
new
ch,
num = 0;
while ((ch = string[stringPos]) > \' \' && ch != delim)
{
switch (ch)
{
case \'x\', \'X\':
{
num = 0;
continue;
}
case \'0\' .. \'9\':
{
num = (num << 4) | (ch - \'0\');
}
case \'a\' .. \'f\':
{
num = (num << 4) | (ch - (\'a\' - 10));
}
case \'A\' .. \'F\':
{
num = (num << 4) | (ch - (\'A\' - 10));
}
default:
{
return -1;
}
}
}
setarg(paramPos, 0, num);
}
case \'c\':
{
setarg(paramPos, 0, string[stringPos++]);
}
case \'f\':
{
setarg(paramPos, 0, _:floatstr(string[stringPos]));
}
case \'p\':
{
delim = format[formatPos++];
continue;
}
case \'\\\'\':
{
new
end = formatPos - 1,
ch;
while ((ch = format[++end]) && ch != \'\\\'\') {}
if (!ch)
{
return -1;
}
format[end] = \'\\0\';
if ((ch = strfind(string, format[formatPos], false, stringPos)) == -1)
{
if (format[end + 1])
{
return -1;
}
return 0;
}
format[end] = \'\\\'\';
stringPos = ch + (end - formatPos);
formatPos = end + 1;
}
case \'u\':
{
new
end = stringPos - 1,
id = 0,
bool:num = true,
ch;
while ((ch = string[++end]) && ch != delim)
{
if (num)
{
if (\'0\' <= ch <= \'9\')
{
id = (id * 10) + (ch - \'0\');
}
else
{
num = false;
}
}
}
if (num && IsPlayerConnected(id))
{
setarg(paramPos, 0, id);
}
else
{
#if !defined foreach
#define foreach(%1,%2) for (new %2 = 0; %2 < MAX_PLAYERS; %2++) if (IsPlayerConnected(%2))
#define __SSCANF_FOREACH__
#endif
string[end] = \'\\0\';
num = false;
new
sscanfname[MAX_PLAYER_NAME];
id = end - stringPos;
foreach (Player, playerid)
{
GetPlayerName(playerid, sscanfname, sizeof (sscanfname));
if (!strcmp(sscanfname, string[stringPos], true, id))
{
setarg(paramPos, 0, playerid);
num = true;
break;
}
}
if (!num)
{
setarg(paramPos, 0, INVALID_PLAYER_ID);
}
string[end] = ch;
#if defined __SSCANF_FOREACH__
#undef foreach
#undef __SSCANF_FOREACH__
#endif
}
stringPos = end;
}
case \'s\', \'z\':
{
new
i = 0,
ch;
if (format[formatPos])
{
while ((ch = string[stringPos++]) && ch != delim)
{
setarg(paramPos, i++, ch);
}
if (!i)
{
return -1;
}
}
else
{
while ((ch = string[stringPos++]))
{
setarg(paramPos, i++, ch);
}
}
stringPos--;
setarg(paramPos, i, \'\\0\');
}
default:
{
continue;
}
}
while (string[stringPos] && string[stringPos] != delim && string[stringPos] > \' \')
{
stringPos++;
}
while (string[stringPos] && (string[stringPos] == delim || string[stringPos] <= \' \'))
{
stringPos++;
}
paramPos++;
}
do
{
if ((delim = format[formatPos++]) > \' \')
{
if (delim == \'\\\'\')
{
while ((delim = format[formatPos++]) && delim != \'\\\'\') {}
}
else if (delim != \'z\')
{
return delim;
}
}
}
while (delim > \' \');
return 0;
}
Ezt beteheted INCbe, vagy ha úgy gondolod, a módba..
Kösz.
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Egyetértek :)
OFF// 250. Hsz :D:D
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Nem,a sscanf a jobb,a futásidejük össze lett hasonlítva, valahol láttam a témát de már nem emlékszem hol,lehet hogy a hiv. fórumon.És ezt nem így kell nézni,hogy melyik kód a hosszabb,attól még dolgozhat gyorsabban.
E:
Ja,bocs,te a kód változatról beszélsz ugye?A plugin verziót kell használni,az pontosan 10X gyorsabb.
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Nem,a sscanf a jobb,a futásidejük össze lett hasonlítva, valahol láttam a témát de már nem emlékszem hol,lehet hogy a hiv. fórumon.És ezt nem így kell nézni,hogy melyik kód a hosszabb,attól még dolgozhat gyorsabban.
E:
Ja,bocs,te a kód változatról beszélsz ugye?A plugin verziót kell használni,az pontosan 10X gyorsabb.
[/quote]
Igen, én a kód változatról beszéltem, mivel az strtok-ot is PAWN nyelven szokták használni. Elfogadom, hogy a sscanf plugin változata jobb mint a PAWN-os strtok.
De mi lenne ha az strtok-ot is pluginban megírná valaki? Az szerintem mindennél gyorsabb lenne. Vagy nem?
KowaZ
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Nem,a sscanf a jobb,a futásidejük össze lett hasonlítva, valahol láttam a témát de már nem emlékszem hol,lehet hogy a hiv. fórumon.És ezt nem így kell nézni,hogy melyik kód a hosszabb,attól még dolgozhat gyorsabban.
E:
Ja,bocs,te a kód változatról beszélsz ugye?A plugin verziót kell használni,az pontosan 10X gyorsabb.
[/quote]
Igen, én a kód változatról beszéltem, mivel az strtok-ot is PAWN nyelven szokták használni. Elfogadom, hogy a sscanf plugin változata jobb mint a PAWN-os strtok.
De mi lenne ha az strtok-ot is pluginban megírná valaki? Az szerintem mindennél gyorsabb lenne. Vagy nem?
KowaZ
[/quote]
Most, hogy kitaláltad mértnem írod meg?
Tudtommal kellõ tudásod megvan hozzá, már csak szabadidõ kell.
Miért mondja mindenki, hogy sokkal gyorsabb és hatékonyabb, mint az strtok? Már a kódjára is elég ránézni: sokkal hosszabb és összetettebb, ezért szerintem lassabb is.
Vagy volt esetleg aki alátámasztotta a gyorsaságát futásidejû összehasonlításokkal? Én szerintem még mindig az strtok a legoptimálisabb megoldás.
KowaZ
Nem,a sscanf a jobb,a futásidejük össze lett hasonlítva, valahol láttam a témát de már nem emlékszem hol,lehet hogy a hiv. fórumon.És ezt nem így kell nézni,hogy melyik kód a hosszabb,attól még dolgozhat gyorsabban.
E:
Ja,bocs,te a kód változatról beszélsz ugye?A plugin verziót kell használni,az pontosan 10X gyorsabb.
[/quote]
Igen, én a kód változatról beszéltem, mivel az strtok-ot is PAWN nyelven szokták használni. Elfogadom, hogy a sscanf plugin változata jobb mint a PAWN-os strtok.
De mi lenne ha az strtok-ot is pluginban megírná valaki? Az szerintem mindennél gyorsabb lenne. Vagy nem?
KowaZ
[/quote]
Szerintem ha ez így lenne,akkor már megcsinálta volna valaki a hiv. fórumon,mégsem tette senki,szerintem ennek oka van.Meg a sscanf sokkal sokoldalúbb is meg egyszerûbb,sokkal több a beálítási lehetõség,bevallom õszintén strtokot nem tudnám használni segítség nélkül,sscanfot meg igen,pedig nem ma kezdtem az ipart.
Különben a sscanf kód verzióját úgy tudom levették a wikirõl is,mivel Y_Less (a készítõ) nem ajálja a használatát.
Akkor a készítõ [Y_Less] tövig kiszophat, minek írta meg, ha nem ajánlja használni?!
20x jobb az strtok, mert nem kell hozzá szaros plugin, se .NET 4.0, sem semmi...
Sokoldalúbb az biztos, de hosszabb, plugin kell hozzá, és több a hibalehetõség..
Lehet hogy sokoldalúbb, viszont tegyük fel a kérdést: Szükség van egy ilyen sokat tudó függvényre?
Én maximum 3 helyen használtam az strtok-ot (amit ki tud váltani a sscanf): parancsok, SQL-lekérdezések és fájlból olvasás. Mindegyik tökéletesen megoldható az strtok-kal.
Extrém esetekhez persze jól jöhet a sscanf, de én akkor is az strtok-ot preferálom, mert nem tudom miért lenne gyorsabb egy olyan függvény, amely ezeregy lehetõséget biztosít. Az emberek 99%-ának meg semmi szüksége rá.
KowaZ
Ti félreértettetek engem,szóval:
Tudjátok van sima PAWN kód és van plugin verzió,és Y_Less a PAWN kód verziót nem ajálja,a plugint igen...
Lehet hogy sokoldalúbb, viszont tegyük fel a kérdést: Szükség van egy ilyen sokat tudó függvényre?
Én maximum 3 helyen használtam az strtok-ot (amit ki tud váltani a sscanf): parancsok, SQL-lekérdezések és fájlból olvasás. Mindegyik tökéletesen megoldható az strtok-kal.
Extrém esetekhez persze jól jöhet a sscanf, de én akkor is az strtok-ot preferálom, mert nem tudom miért lenne gyorsabb egy olyan függvény, amely ezeregy lehetõséget biztosít. Az emberek 99%-ának meg semmi szüksége rá.
KowaZ
Ez különösen a parancsoknál hasznos....Ott van használva a legtöbbször.
Én rengeteg funkcióját használom,mert sokkal könnyebb velük minden.Szerintem te azért mondod ezt,mert nem tudod mire is képes.Adok egy hiv. fórum linket:
http://forum.sa-mp.com/showthread.php?t=120356&highlight=sscanf2+plugin
Le van írva minden A-tól Z-ig .
Ez így van, de tegyük fel a kérdést: Miért ne használjunk egy sokoldalúbb algoritmust, ha az gyorsabb is mint az strtok?
[/quote]
Egyetértek.
Készítettem egy futásidõ mérõ tesztet a pluginos sscanf és a PAWN-os strtok esetében, ami alapján a sscanf gyorsabbnak bizonyult. Már csak az a kérdés, hogy ha pluginban lenne mind a kettõ, akkor milyen eredményre jutnánk.
KowaZ
Akkor a készítõ [Y_Less] tövig kiszophat, minek írta meg, ha nem ajánlja használni?!
20x jobb az strtok, mert nem kell hozzá sz*ros plugin, se .NET 4.0, sem semmi...
Sokoldalúbb az biztos, de hosszabb, plugin kell hozzá, és több a hibalehetõség..
Azt elõbb írta meg, a plugin változatát pedig késõbb, ezért már nem ajánlja a régit.
Készítettem egy futásidõ mérõ tesztet a pluginos sscanf és a PAWN-os strtok esetében, ami alapján a sscanf gyorsabbnak bizonyult. Már csak az a kérdés, hogy ha pluginban lenne mind a kettõ, akkor milyen eredményre jutnánk.
KowaZ
Ez nem kérdés, gyorsabb lenne mert egy egyszerûbb algoritmus.
[/quote]
Tehát mégis csak jobb az strtok használata az általam említett egyszerû (hétköznapi) esetekre. Csak meg kell írni C++ban. Köszönöm a közremûködéseket!
KowaZ
Ilyen egyszerû dolgokért miért kérsz tanácsot?
Ilyen egyszerû dolgokért miért kérsz tanácsot?
Egyszerû? Akkor megkérnélek, hogy készítsd el az strtok plugin változatát.
KowaZ
Veszekedést félretéve, hogy csináljam, hogy egy karakterláncot, vagy egy játékos Idt fogadjon el? [mint pl \"u\", felhasználónév/id] //Gang Scripthez kell
Egy példa, ha gangnál ID vagy név szerint akarsz választani:
CMD:car(playerid, params[])
{
carid,
if(sscanf(params, \"s[128]\", i_str)) return SendClientMessage(playerid, COLOR_RED, \"HASZNÁLAT: /car <Model ID/Név>\");
if(!IsNumeric(i_str))
{
carid = GetVehicleModelIDFromName(i_str);
}
else
{
carid = strval(i_str);
}
vID = CreateVehicle(carid, X, Y, Z, Angle, color[0], color[1], -1);
return 1;
}
Mármint úgy, hogy CMD:gang
akkor az elsõ paraméter, a \"create, join, quit\", ilyenek string
második paraméter a joinnál az ID, createnél, meg invitenél meg egy név, azaz string.
ezt hogy lehet
CMD:car(playerid, params[])
{
carid,
if(sscanf(params, \"s[128]s[128]\", i_str, tmp)) return SendClientMessage(playerid, COLOR_RED, \"HASZNÁLAT: /car <Join/Leave> <Model ID/Név>\");
if(!strcmp(i_str, \"join\", true))
{
if(!IsNumeric(tmp))
{
carid = GetVehicleModelIDFromName(tmp);
}
else
{
carid = strval(tmp);
}
}
else if(!strcmp(i_str, \"leave\", true))
{
if(!IsNumeric(tmp))
{
carid = GetVehicleModelIDFromName(tmp);
}
else
{
carid = strval(tmp);
}
}
else SendClientMessage(playerid, COLOR_RED, \"Hülye vagy\");
return 1;
}
Kössz :D
nm xD
A kód formátumú kezeli az elválasztásokat?
Vagy esetleg nálam van a hiba?
sscanf(Line,\"p<|>{ds[25]}s[20]{s[25]s[25]ddddddd}\",Password);
A kód formátumú kezeli az elválasztásokat?
Vagy esetleg nálam van a hiba?
sscanf(Line,\"p<|>{ds[25]}s[20]{s[25]s[25]ddddddd}\",Password);
Ez bug, de attól függetlenül megy, nálam is ezvan. Y_Less-nek már jelentettem, de még nem javította.
És kilehet valahogy küszöbölni?
És kilehet valahogy küszöbölni?
Hááát... Ez attól függ, hogy hol használod.
Karakteres elválasztás hozzáadva!
Letöltést link frissítve az újabb sscanf kiadás miatt!
MySQL scripteknél észrevettem,hogy szintee mindegyik scipt úgy épül fel,hogy az sscanf segítségével választjuk ki az adatokat!
[pawn]new values[5];
sscanf(Query, \"p<|>{s[24]s[129]s[16]}a<i>[5]\", values);
SetPVarInt(playerid, \"Admin\", values[0]);
GivePlayerMoney(playerid, values[1]);
SetPlayerScore(playerid, values[2]);
SetPVarInt(playerid, \"Kills\", values[3]);
SetPVarInt(playerid, \"Deaths\", values[4]);
SetPVarInt(playerid, \"Logged\", 1);[/pawn]
És ezt még megszeretném érteni valahogy, tehát valaki megtudná nekem mondani,hogy pl az accounts táblából hogyan válasszam ki a LastOn-t,RegDate-t,GameTime-t,Skin-t?
MySQL scripteknél észrevettem,hogy szintee mindegyik scipt úgy épül fel,hogy az sscanf segítségével választjuk ki az adatokat!
[pawn]new values[5];
sscanf(Query, \"p<|>{s[24]s[129]s[16]}a<i>[5]\", values);
SetPVarInt(playerid, \"Admin\", values[0]);
GivePlayerMoney(playerid, values[1]);
SetPlayerScore(playerid, values[2]);
SetPVarInt(playerid, \"Kills\", values[3]);
SetPVarInt(playerid, \"Deaths\", values[4]);
SetPVarInt(playerid, \"Logged\", 1);[/pawn]
És ezt még megszeretném érteni valahogy, tehát valaki megtudná nekem mondani,hogy pl az accounts táblából hogyan válasszam ki a LastOn-t,RegDate-t,GameTime-t,Skin-t?
Nem egészen,a sscanf az adatok feldolgozására (jelen esetben a karakterlánc feldarabolásáûra és az értékek változókba helyezése) a feladata. Az adatokat a mysql pluginunk beépített fügvényével választjuk ki,álltalában ez a mysql_query.
Ha kiválasztasz egy sort az adatbázisodból ez így épül fel:
1|kadaradam|40000|2011-10-10|asdasd
És ezt a karakterláncot vágja fel a ssancf neked és rakja változókba. Hogy ezeket hogyan szedd ki mysql-ból le van írva ebben az alfórumban a mysql tutorialomban.
0.3d-hez .dll + forráskód
Ezt már nemkell újítani, mivel SAMP GDK-val van megoldva.
Kösz, kicseréltem a linket a fõposztban. ;)
Nincs mit.
Bár szerintem még nem fontos cserélni, mivel ez csak windows-hoz van (jelenleg) és nem Y_Less adta ki hivatalosan :D
Majd ha lesz idõd, akkor az Tömbök betöltésével is írhatnál hozzá pár dolgot, az is sokat segítene sokmindekinnek, mert sokan azt se tudják, hogy mi az.
Példa:
[pawn]
new
WeaponSkill[11],
sscanf(i_str, \"p<,>A<i>(0)[11]\", WeaponSkill);
[/pawn]
Hát az a helyzet, hogy én már egy ideje leálltam ezzel az egész szkripting dologgal, de ha veszed a fáradtságot, és megírsz egy részt arról/azokról a dolgokról amiket hiányolsz, és elküldöd nekem PM-ben, akkor beillesztem a fõposztba, és természetesen feltüntetem a nevedet is mellette. :)
Nekem ezzel az a bajom hogy csinál mg egy login/register de nem is jegyzi meg mindig registration valaki ötlet kikapcsolására?
Nekem ezzel az a bajom hogy csinál mg egy login/register de nem is jegyzi meg mindig registration valaki ötlet kikapcsolására?
Hát ezt sajnos nem teljesen értettem.
Eddig volt nekem saját login/register systeme és mióta beraktam a sscanfot azóta van egy másik lett hirtelen kick bann és hasonló parancsok pedig be se raktam és hogy ezt nem lehet valahogy kikapcsolni vagy valahogy kivenni mert ezek nekem nem kellenek csak a csupasz sscanf
Újabb verzió elérhetõ!
sscanf 2.5 letöltése!
Írtam hozzá pár dolgot. Ajánlom a legelsõ részét elolvasni.
- Custom (kustom) specifiers
A legújabb sscanf verzióban bekerült egy új elválasztó, ami a \"k\". E elválasztó segítségével létre lehet hozni saját specifiert.
SSCANF:playerstate(string[])
{
if (\'0\' <= string[0] <= \'9\')
{
new
ret = strval(string);
if (0 <= ret <= 9)
{
return ret;
}
}
else if (!strcmp(string, \"PLAYER_STATE_NONE\")) return 0;
else if (!strcmp(string, \"PLAYER_STATE_ONFOOT\")) return 1;
else if (!strcmp(string, \"PLAYER_STATE_DRIVER\")) return 2;
else if (!strcmp(string, \"PLAYER_STATE_PASSENGER\")) return 3;
else if (!strcmp(string, \"PLAYER_STATE_WASTED\")) return 7;
else if (!strcmp(string, \"PLAYER_STATE_SPAWNED\")) return 8;
else if (!strcmp(string, \"PLAYER_STATE_SPECTATING\")) return 9;
}
Ha ezt a kódot belerakod a módodba, akkor ez hozzáadja a \"playerstate\" nevû specifier-t. Következõ képpen tudod ezt használni:
[pawn]
sscanf(params, \"uk<playerstate>\", playerid, state);
[/pawn]
Ez a rendszer szintén támogatja az alapértelmezett értéket. Itt a az alapértelmezett érték a \"PLAYER_STATE_NONE\" lesz:
[pawn]
sscanf(params, \"uK<playerstate>(PLAYER_STATE_NONE)\", playerid, state);
[/pawn]
Az új \"sscanf2.inc\" függvénykönyvtár tartalma két darab specifier-t. Ez a \"k<weapon>\" és a \"k<vehicle>\". Ennek a segítségével letudsz hívni fegyvert/kocsit ID, vagy név szerint. Ha nem ID-t írsz, akkor lefut a \"weapon\"/\"vehicle\" rész és név szerint kikeresi neked az ID-t és azzal tér vissza.
Az egyéni specifier-ek nem támogatják a tömböket és az enumokat!
Jegyezd meg, hogy az egyedi specifier-nek a bemenet típusa mindig karakterlánc, és mindig egy számmal tár vissza. Ez lehet Float, bool, vagy akármilyen más egy cellás tag típus.
Keresni egy általunk beírt karakterláncra egy megadott karakterláncban a következõ képpen tudunk:
[pawn]sscanf(\"10 11 woo 12\", \"i\'woo\'i\", var0, var1);[/pawn]
A kimenet a következõ lesz:
var0 = 10
var1 = 12
- Fent-e van a játékos a szerveren
Rengeteg helyen észreveszem, hogy a beírt ID-t IsPlayerConnected() el ellenõrzik le.
Ez pedig felesleges, mivel az sscanf-nél ha az \"u\" paramétert használod, akkor az automatikusan leellenõrzni, hogy a játékos csatlakozva-e van. Ha nincs, akkor 0xFFFF-el fog visszatérni = (65535 = INVALID_PLAYER_ID).
Tehát elég lenne ennyit is csinálni:
[pawn]if(sscanf(params, \"ui\", player1, score)) return SendClientMessage(playerid, COLOR_RED, \"HASZNÁLAT: /setscore <Játékos ID/Név> <Pont>\");
if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, COLOR_RED, \"HIBA: Játékos nincs csatlakozva!\");
[/pawn]
Szerintem nem éri meg váltani sscanf 2.5-re, a szerverem be bugolt miatta..Visszaraktam a régi sscanf-et a 2.0-t és egybõl jó lett
Töröld a callback hook rendszert az include-bõl, és írd bele a módodba!
Nekem is ezvolt a problémám, megcsináltam és ment minden.
De szerintem ezt Y_Less javítani fogja..
Ok majd megcsinem, kösz kurta!:D
Elérhetõ a 2.6-os verzió, abban már javítva van az \"u\" paraméter, amikor nemlétezõ játékosokra nem INVALID_PLAYER_ID-vel tért vissza.
Megjelent a 2.8.1-es verzió, amiben nagyon sok hasznos új lehetõség bekerült.
Érdemes elolvasni újra az üzenetet, nem írom ki mik az újak benne.
http://forum.sa-mp.com/showthread.php?t=120356
Én mindent úgy csináltam, ahogy kell, ahogy szépen leírtad, de érdekes!!! Nekem miért nem jó, és amúgy NINCSEN BENNE az sscanf2.inc abba a letöltési mappádba se... és nem ismeri fel, ha beleteszem, ha beleírom a server mappába a plugins-t, és az elejére is a scriptnek ,semmi, valyon miért lehet, valaki help pls, mert már a vérnyomásom min. 1000-en van :D
A téma indítója, szerintem most forgott meg a sírjában.
A téma indítója, szerintem most forgott meg a sírjában.
Elhunyt? :\'(