Jump to content

Format


Guest Justin Bieber

Recommended Posts

Format je funkce která "formátuje" něco do proměnných (třeba text).

 

format má tyto parametry -

 

format(var, sizeof, string[]);

 


  • [*:xtbx8lqd] var
    [*:xtbx8lqd] sizeof
    [*:xtbx8lqd] string[]

 

var - Nazev promene do ktere vepiseme text

sizeof - Pocet znaku, pokud pouzijete sizeof() tak to znamena ze pocet znaku bude shodny s poctem znaku v promenne napsane mezi ( )

new string[500];
sizeof(string) // max. pocet znaku bude 500

string[] - Zde se zapisuje text mezi ""

 

A za tyto tri parametry se muze psat dalsich parametru haba dej :) Tam se davaji treba nazvy promenych kdyz chceme vypsat jeji obsah, ale o tom se dozvime nize ;)

 

Co potřebujeme k formátování

1. Proměnou do které vložíme formátovaný text

2. Funkci kterou odešleme zformátovaný text

3. Funkci format ;)

 

Příklad vypsání hráčova jména

new name[24]; // Proměna pro hráčův nick
GetPlayerName(playerid, name, sizeof(name)); // Hráčův nick se zkopíruje do proměnné name
new string[80]; // viz. bod 1
format(string,sizeof(string),"Hracuv nick: %s", name); // Bod 3
SendClientMessageToAll(0xFFFFFAA, string); // Bod 2

 

Vsimli jste si znaku %s ? Takto se označuje když chceme vložit string neboli text. Zde je seznam NEJPOUZIVANEJSICH 3 znaků, zbytek je ZDE -

 


  • [*:xtbx8lqd]%d Kdyz chceme vypsat ciselnou hodnotu dame tam toto ;)
    [*:xtbx8lqd]%f Vlozi Float (desetine cislo)
    [*:xtbx8lqd]%s Vlozi string (text)

 

Příklad použití více proměn

new pawn;
new pawno;

GetPlayerName(playerid, pawn, sizeof(pawn));
GetPlayerMoney(playerid, pawno);

new string[100];
format(string, sizeof(string), "Hrac %s ma %d penez!", pawn, pawno);
SendClientMessageToAll(0xFFFFFAA, string);

 

Cili jsme vytvorili dve promenee

Do jedne vepsali hracuv nick a do druhe stav hracovych penezi.

A ted prisla formatovaci akce kdyz jsme na hracovo jmeno pouzili %s a na stav penez %d.

 

Hlavne si davejte pozor na poradi promen v 4 parametru, pokud by jste zamenili pawno s pawn tak se vam to nevypise ;)

 

Pamatujte ze pokud chcete vypisovat obsah promene, musite pouzit format !!

 


 

Doufám že jste to pochopili a pokud máte dotaz napište.

 

Wiki: [w]Format[/w]

Link to comment
Share on other sites

Fakt Pekný navod 10/10

Tys ho precetl cely? Za necely 2 minuty? Ja teda ne, stihl jsem jenom var :d Ale jdu to docist, pekne popsany ale :thumbup:

 

"lol" Ved Som to cital ale ne cele ale vydim ze je to dobre .. Je to aj pekne vystvetlene omg este viem co pisem !!

Link to comment
Share on other sites

Pekný tut, chválim :) presne tento som dneska hladal (zdalo sa mi že freewall takýto robil ale nerobil, tak to potom na pawno boxe je od mavericka :)) toto je jeden z tých dobrých tutov :) ktoré niečo naučia a nie ctrl + c

ps. ešte by si mohol pridať

 

stock SCM(playerid, color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 3;

new dest[512];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessage(playerid,color,dest);

}

 

stock SCMTA(color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 2;

new dest[128];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessageToAll(color,dest);

}

 

aby človek nemusel stále dávať new string... :)

 

Link to comment
Share on other sites

Pekný tut, chválim :) presne tento som dneska hladal (zdalo sa mi že freewall takýto robil ale nerobil, tak to potom na pawno boxe je od mavericka :)) toto je jeden z tých dobrých tutov :) ktoré niečo naučia a nie ctrl + c

ps. ešte by si mohol pridať

 

stock SCM(playerid, color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 3;

new dest[512];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessage(playerid,color,dest);

}

 

stock SCMTA(color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 2;

new dest[128];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessageToAll(color,dest);

}

 

aby človek nemusel stále dávať new string... :)

Lol.. nice ten stock QWER :) :thumbup:

Link to comment
Share on other sites

stock SCM(playerid, color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 3;

new dest[512];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessage(playerid,color,dest);

}

 

stock SCMTA(color, const msg[], {Float,_}:...)

{

new len = strlen(msg),d=0,posArg = 2;

new dest[128];

for(new i=0;i

{

if(msg == '%')

{

switch (msg[i+1])

{

case 's':

{

new pos,arg,tmppos;

new str[128];

while(getarg(posArg,pos)!='\0')

{

arg=getarg(posArg,pos++);

str[tmppos]=arg;

tmppos++;

}

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'i', 'd':

{

new str[128];

format(str,sizeof(str),"%d",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case 'f':

{

new str[128];

format(str,sizeof(str),"%f",getarg(posArg));

strins(dest,str,d,strlen(str));

d+=strlen(str);

posArg++;

i++;

}

case '.':

{

new len2 = msg[i+2];

if(len2 == 0)

{

dest[d] = msg;

d++;

}

else

{

new str[32],formatting[5];

formatting[0] = '%';

formatting[1] = '.';

formatting[2] = len2;

formatting[3] = 'f';

format(str,sizeof(str),formatting,getarg(posArg));

strins(dest,str,d,len2);

d+=len;

posArg++;

i+= 2;

}

}

default:

{

dest[d] = msg;

d++;

}

}

}

else

{

dest[d] = msg;

d++;

}

}

return SendClientMessageToAll(color,dest);

}

 

aby človek nemusel stále dávať new string... :)

 

Myslim ze novacci, kdyby tohle videli tak by rychle utekli, je to sice fajnovy ze das jen jednu funkci a nemusis delat to co sem psal nahore ale ja mam radsi, kdyz se clovek uci bez stocku a podobnych zjednoduchovatin protoze pak kdyz se to nauci a nekomu chce radit tak bude tak zblblej ze mu zacne radit pouzij SCMwFormat (vymyslene :d ).

Link to comment
Share on other sites

  • 4 months later...
  • 6 years later...

Uvedomujem si, že tento návod je starý už dosť dlho. Ale nebudem kvôli mojej otázke vytvárať new topic.

Som pokročilý pawner, ale mám aj tak otázku. Ako mám zapísať, keď v jednom formáte chcem mať 2 premenné na text?

Niečo ma napadlo, ale neviem či je to 100% dobre. Preto prosím o kontrolu :d.

Spoiler

 

new meno1;

new meno2;

GetPlayerName(playerid, meno1, sizeof(meno1));

GetPlayerName(playerid, meno2, sizeof(meno2));

 

new string; //Otázka: Tu musí byť string, alebo tam tiež môžem dať svoj názov?

format(string, sizeof(string), "Admin %s dal hracovi %s Admin Prava!", meno1, meno2);

SendClientMessageToAll(-1, string);

 

 

Link to comment
Share on other sites

Nájdi si niekde stock PlayerName ktorý dáš hore do módu a potom ten format bude vyzerať takto:

 

format(string, sizeof(string), "Admin %s dal hracovi %s Admin Prava!", PlayerName(playerid), PlayerName(id));

SendClientMessageToAll(-1, string);

 

  • Nope 4
Link to comment
Share on other sites

Pekný tutorial pre nováčikov.. Ale.. Sú to nováčikovia, jak im povieš, tak to budú robiť vždy, takže čo si dal to "Viac premien"..

new pawn;
new pawno;

Vždy budú davať premenné do dalších  riadkov, tak tam aj pripíš že to môžu dávať aj do riadku..

new pawn, pawno;

 

Link to comment
Share on other sites

  • Hlavní moderátor
12 minutes ago, IllidanS4 said:

Takto rozhodně ne! Používat takováto arbitrární čísla jako 100, 128, 256 apod. jako velikost řetězce je holý nesmysl – zbytečně alokujete na zásobníku víc místa, než kolik nakonec využijete. Dobrý pawner neplýtvá místem (zvláště ne na zásobníku). Jméno hráče má nejvýše MAX_PLAYER_NAME - 1 znaků, "nejdelší" číslo (-2147483648) má znaků 11 a samotný text jich má 16. Správná velikost bufferu je tedy 27 + MAX_PLAYER_NAME (+1 buňka na ukončující nulový znak). Méně buněk nemusí stačit a více bude zaručeně plýtvat místem.

Povšimněte si, že místo 24 píšu MAX_PLAYER_NAME. To je taky dobrý zvyk, protože definice se mohou vždy změnit, a až (když) nová verze SA-MPu zvýší velikost jména z 24 znaků na 32, přeji vám hledat ve vašem kódu všechna místa, kde to bude potřeba opravit. ;-)

Také doporučuji použít namísto kombinace format + SendClientMessage nějakou alternativu SendClientMessageFormat. Existuje verze používající #emit a plugin YSF přidává SendClientMessagef.

Nezapomeňte, že do řádku v chatu se vejde nejvýše 143 znaků. Pokud tedy chcete formátovaný řetězec ukazovat v chatu, použijte nejvýše velikost MAX_CHATBUBBLE_LENGTH. Chybou (či úmyslem, nevím) SA-MP je taky to, že pokud zasíláte přes SendClientMessage znak %, pochopí ho to jako formátovací specifikátor (ačkoliv SendClientMessage nemá formátovat) a může to i shodit server. Použijte %%.

Hezký příspěvek. Nicméně v jednom s tebou nesouhlasím – do chatu lze zaslat zprávu o délce 144 znaků. A než to řekneš, tak ano, počítám i s nulovým znakem ukončující řetězce, proto u zprávy do chatu s variabilní délkou, která může dosáhnout maxima (např. zpráva o zabanování hráče, kam lze vložit důvod), se používají pole s velikostí 145 (144 + EOS).

Link to comment
Share on other sites

10 minutes ago, vEnd said:

Hezký příspěvek. Nicméně v jednom s tebou nesouhlasím – do chatu lze zaslat zprávu o délce 144 znaků. A než to řekneš, tak ano, počítám i s nulovým znakem ukončující řetězce, proto u zprávy do chatu s variabilní délkou, která může dosáhnout maxima (např. zpráva o zabanování hráče, kam lze vložit důvod), se používají pole s velikostí 145 (144 + EOS).

Máš pravdu. Mylně jsem doufal, že SA-MP bude pro jednou konzistentní. :-D

  • Haha! 1
Link to comment
Share on other sites

2 hours ago, IllidanS4 said:

Takto rozhodně ne! Používat takováto arbitrární čísla jako 100, 128, 256 apod. jako velikost řetězce je holý nesmysl – zbytečně alokujete na zásobníku víc místa, než kolik nakonec využijete. Dobrý pawner neplýtvá místem (zvláště ne na zásobníku). Jméno hráče má nejvýše MAX_PLAYER_NAME - 1 znaků, "nejdelší" číslo (-2147483648) má znaků 11 a samotný text jich má 16. Správná velikost bufferu je tedy 27 + MAX_PLAYER_NAME (+1 buňka na ukončující nulový znak). Méně buněk nemusí stačit a více bude zaručeně plýtvat místem.

Povšimněte si, že místo 24 píšu MAX_PLAYER_NAME. To je taky dobrý zvyk, protože definice se mohou vždy změnit, a až (když) nová verze SA-MPu zvýší velikost jména z 24 znaků na 32, přeji vám hledat ve vašem kódu všechna místa, kde to bude potřeba opravit. ;-)

Také doporučuji použít namísto kombinace format + SendClientMessage nějakou alternativu SendClientMessageFormat. Existuje verze používající #emit a plugin YSF přidává SendClientMessagef.

Nezapomeňte, že do řádku v chatu se vejde nejvýše 143 znaků. Pokud tedy chcete formátovaný řetězec ukazovat v chatu, použijte nejvýše velikost MAX_CHATBUBBLE_LENGTH. Chybou (či úmyslem, nevím) SA-MP je taky to, že pokud zasíláte přes SendClientMessage znak %, pochopí ho to jako formátovací specifikátor (ačkoliv SendClientMessage nemá formátovat) a může to i shodit server. Použijte %%.

Jedna sa o desiatky az stovky bajtov. Absolutne na tom nezalezi, ak si to porovnas napr. s tym, co alokuje java...

Co ti vlastne prinesie tato optimalizacia a kolko casu bude stat? Ak mas v mode 1000 miest, kde pouzivas new str[512]; ktore optimalizujes, usetris tak 367 KB RAM a optimalizacia takeho modu ta bude stat 1-2 dni casu (ak nie viac). 

Z toho usudzujem 2 veci:
Je to teoreticky zaujimave? Ano.
Oplati sa to? Nie.

 

Takato optimaliziacia by bola zaujimava, ak by dany mod bezal na 8 bitovom arduine.

Link to comment
Share on other sites

  • Administrátor
45 minutes ago, Asakura Yoh said:

Jedna sa o desiatky az stovky bajtov. Absolutne na tom nezalezi, ak si to porovnas napr. s tym, co alokuje java...

Co ti vlastne prinesie tato optimalizacia a kolko casu bude stat? Ak mas v mode 1000 miest, kde pouzivas new str[512]; ktore optimalizujes, usetris tak 367 KB RAM a optimalizacia takeho modu ta bude stat 1-2 dni casu (ak nie viac). 

Z toho usudzujem 2 veci:
Je to teoreticky zaujimave? Ano.
Oplati sa to? Nie.

 

Takato optimaliziacia by bola zaujimava, ak by dany mod bezal na 8 bitovom arduine.

To máš nejspíš pravdu ale když se na to vykašleš uplně tak se to potom odrazí na plynulosti hry... Mám zkušenost kdy měl týpek mód kde používat na jméno 1024 , samozřejmě nebylo to jen to ale jakmile někdo udělal cokoliv ( vyvolal dialog, šlapl na pickup ) automaticky měl cely server lag. Já osobně si myslím že té optimalizaci by se člověk věnovat měl, proč ten kód nepsat rovnou pěkně a optimalně a když ně kvůli serveru tak alespon kvůli sobě 

Link to comment
Share on other sites

1 hour ago, Asakura Yoh said:

Jedna sa o desiatky az stovky bajtov. Absolutne na tom nezalezi, ak si to porovnas napr. s tym, co alokuje java...

Co ti vlastne prinesie tato optimalizacia a kolko casu bude stat? Ak mas v mode 1000 miest, kde pouzivas new str[512]; ktore optimalizujes, usetris tak 367 KB RAM a optimalizacia takeho modu ta bude stat 1-2 dni casu (ak nie viac). 

Z toho usudzujem 2 veci:
Je to teoreticky zaujimave? Ano.
Oplati sa to? Nie.

 

Takato optimaliziacia by bola zaujimava, ak by dany mod bezal na 8 bitovom arduine.

Jen malé zpřesnění výpočtů, nezapomínej, že buňka v AMX má 4 bajty, takže pro takový počet polí ušetříš téměř 1,5 MB (4*(512-145)*1000/1024 KB). Každé pole zabírá čtyřnásobek své délky (a SA-MP zrovna moc vehementně char-array nepropaguje). Samozřejmě na moderních strojích není taková alokace výrazná, ale AMX je neoptimalizovaná interpretovaná platforma, a jak ještě Y_Less doplňuje, takové pole je inicializováno, což se už v cyklu lehce projeví rychlostí (samotné pole se pamětí projeví spíše v rekurzi).

Ta "teorie" se může v praxi lehce projevit, a navíc když člověk jednou programuje, měl by programovat pořádně, zvláště když to nestojí moc úsilí na tohle myslet.

  • Líbí se mi to! (+1) 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...