Přejít na obsah

sscanf2 - int, string, enum, pole [***]

Scydo SkiBig18 Y_Less sscanf2 sscanf params parametry

  • Pokud chcete odpovědět, přihlaste se
3 odpovědí

#1
SkiBig18

SkiBig18

    Expert ve satanistickém díle YSI4

  • Uživatel
  • Příspěvků: 1 254
  • Je tu celkem: 10d 13h 22m 14s

sscanf2
*****

Zdravím vás u dalšího návodu, konkrétně o velice populárním a dost často používaném pluginu a to sscanf. Jde o plugin, který mnoha uživatelům vypomáhá při tvorbě více parametrových příkazů či u více informačních údajů(například inputtext) v samp.

Obsah

  • Ukázka použití
  • Specifikátory
    • Integer
    • String
    • Pole
    • Enum
  • Velké specifikátory
    • Integer
    • String
    • Pole
    • Enum
  • Použití
    • Změnit hráčovi počet životů
    • Zabanovat hráče s důvodem
    • Nahrát více údajů v jednom souboru
  • Download
  • Závěr

Ukázka použití

Hodně uživatelů využívá tuhle funkci hlavně v podmínkách v příkazech, například:




if (sscanf(params, "ui", ID, Penize)) 
	return SendClientMessage(playerid, -1, "Použití: /prachy [ID/Jméno hráče] [Počet]");

Jak to funguje? Vezme údaje ze params, a z celého řetězce zjistí, kde tam jsou dané datové typy, a to u nebo-li string(číslo nebo nick hráče, či jeho součást) a i nebo-li integer, a dosadí do daných proměnných(ID a Peníze), a podmínka nám vrací true/false dle toho, zda při rozdělovaní (ne)vzniknou nějaké komplikace, například jeden z údajů chybí, nebo nenašel v řetězci daný datový typ(například místo čísla aka peněz napíšete nějaký string. Funkce to vyhodnotí jako text, nikoliv číslo a chyba).

Spoiler

V případě, že jste to nepochopili, můžeme si to ukázat na jiném příkladě. Jelikož sscanf2 je funkce, lze jí jednoduše používat i bez podmínek:




	new
	    String[15] = "abcd",
	    Cislo = 0;
	sscanf("Potrebuji 1000", "si", String, Cislo);
	printf(" %s %i", String, Cislo);

Právě jsme si deklarovali 2 proměnné a to String a k němu jsme si přiřadili hodnotu "abcd" a proměnnou Cislo s přiřazenou hodnotou 0. Nyní využijeme fci sscanf, aby vzal daný řetězec a to Potrebuji 1000 a rozdělil je do těchto 2 proměnných. Jak si můžete všimnout, obsahuje 2 datové typy a to string a integer. Takže jelikož první údaj je string tak logicky první specifikátor(o nich později) bude s, a druhé je číslo, takže specifikátor bude i. Nyní se nám za proměnné dosadí oba údaje a do konzole se nám vypíše Potrebuji 1000, a ne abcd 0.

Spoiler


Specifikátory

Nebudu tu vypisovat všechny specifikátory, které sscanf obsahuje, ale jen prozatím ty, které uživatelé používají asi nejčastěji:


SpecifikátorJménoPříklad

i, d

Integer4, 72, -1024

s

StringAhoj, Admin, sb75c4

l

Booleantrue, false

f

Float0.5, 33.1, -99.9

h, x

HexFF, 0xAD35

u

Jméno/ID hráče a botůSkiBig18, 2

r

Jméno/ID hráčeSkiBig18, 2

  • Integer

Specifikátor se značí písmenkem i nebo d. Nejjednoduší specifikátor. Jde rozdělit 2 nebo i více řad čísel do daných proměnných, například:



	new 
		Cislo1 = 0, Cislo2 = 0;

	sscanf("100 200", "ii", Cislo1, Cislo2);
	printf("%i %i", Cislo1, Cislo2);
	/* Vypíše 100 200 */

Není problém ani s řadou čísel, jen si musíte hlídat počet íček:



	new
		Cislo[6];

	sscanf("1 4 9 2 -1 5", "iiiiii", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);
	printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);

V případě, že vynecháte jedno z íček, sscanf poslední hodnotu specifikuje jako 0 a také jí dosadí. To stejné platí i u stringu:



	sscanf("1 4 9 2 -1 5", "iiiii", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);
	printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);
	/* Vypíše 1 4 9 2 -1 0 */

Lze nahradit písmeno i také písmenem d, výsledek i efekt bude naprosto stejný:



	sscanf("1 4 9 2 -1 5", "dddddd", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);
	printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]);
	/* Vypíše 1 4 9 2 -1 5 */
  • String

Specifikátor se značí písmenkem s. Další nejčastěji používaný specifikátor. Používá se hlavně v příkazech pro důvody. Ale sscanf2 nabízí více možností práce se stringem.
Jak jsem již na začátku ukazoval, kód:



	sscanf("Potrebuji 1000", "si", String, Cislo);

Vypíše Potrebuji 1000. Ale co, když chceme do první proměnné přidat ještě slovo?



	sscanf("Potrebuji ihned 1000", "s[10]i", String, Cislo);

Tak selže dosazování, jelikož slovo ihned není číslo, a po slově Potrebuji doplní nulu a tím končí. Řešení je prosté. Stačí buď přidat další specifikátor:



	new
		String[2][10], Cislo;
	sscanf("Potrebuji ihned 1000", "s[16]s[6]i", String[0], String[1], Cislo);
	printf("%s %s %i", String[0], String[1], Cislo);
	/* Vypíše Potrebuji ihned 1000 */

A nebo vynechat číslo a nechat jen jeden specifikátor pro celý text:



	new
		String[16];
	sscanf("Potrebuji ihned", "s[16]", String);
	print(String);
	/* Vypíše Potrebuji ihned */

Ale problém je teď, že specifikátor vezme celý text, nebo-li všechno po slovech Potrebuji ihned(pokud samozřejmě bude mít větší délku). V případě, že potřebujeme jen samostatně jediné slovo, stačí přidat po specifikátoru mezeru:



	new
		String[16];
	sscanf("Potrebuji ihned", "s[16] ", String);
	print(String);
	/* Vypíše Potrebuji */

Spoiler

  • Pole

Specifikátor se značí písmenkem a<>. Práce s polem u sscanf je podobné jako stringu, s tím rozdílem, že velikost pole nepoužíváme jako délku, ale k dosazení počtu prvků, a za každý prvek se dosadí daná hodnota v poli určité proměnné, například:



	new
	    Pole[5];
	sscanf("1 3 8 6 2", "a<i>[5]", Pole);
	printf("%i %i %i %i %i", Pole[0], Pole[1], Pole[2], Pole[3], Pole[4]);
	/* Vypíše 1 3 8 6 2 */

Jak si můžete všimnout, specifikátory pro jediné pole jsou 2 a to a(array v překladu pole), a i jako integer. Aby si sscanf nepletlo pole a velikost retězce, využíváme na začátek specifkátoru pro pole, jiné závorky, a to <>. Specifikátor i pak obsahuje datové typy pole nebo-li čísla. A nakonec [5] je maximální počet buněk v poli.

Samozřejmě lze kombinovat i jiné datové typy v poli, například string:



	new
	    String[3][3 + 1];
	sscanf("Abc Ab A", "a<s[4]>[3]", String);
	printf("%s %s %s", String[0], String[1], String[2]);
	/* Vypíše Abc Ab A */

Jak to funguje tady? Deklarovali jsme si 3 řetězce s počtem 4 znaků (3 + nul. znak). Za každý řetězec dosadí specifická písmena. Je to úplně stejné jako bychom retězci0( String[0] ) přiřadili hodnotu "Abc", řetězci1( String[1] ) hodnotu "Ab" a řetězci2( String[2] ) hodnotu "A".

  • Enum

Specifikátor se značí písmenkem e<>. Tento dodatek se považuje za nejlepší dodatek v sscanf. A ani se nedivím, jelikož vám umožní měnit výčet hodnot dokonce v samotném enumu. A jako u pole i zde platí, že lze přepsat všechny datové typy. Ale je to pár rozdílů, jeden z nejrelevantnějších je, že musíte vypsat všechny specifikátory všech datových typů, co enum obsahuje(logicky, jinak by sscanf nevěděl, jakou proměnnou má přesně v enumu přepsat). Ukážeme si to na příkladu:



	enum enum_PlayerInfo {

		e_AdminLevel,
		e_VipLevel,
		e_VipBodu,

	}

	new
		e_Enum[enum_PlayerInfo];

	sscanf("5 1 1000", "e<iii>", e_Enum);
	printf("%i %i %i", e_Enum[e_AdminLevel], e_Enum[e_VipLevel], e_Enum[e_VipBodu]);
	/* Vypíše 5 1 1000 */

Zde jsem si deklarovali proměnnou s výčtem hodnot, který obsahuje AdminLevel, VipLevel a počet bodů. Sscanf nám zjistí ze všech specifikátorů ve specifikaci struktury v enumu(nebo-li v <>), že jde o čísla a tak přepíše hodnoty. Ano, práce s polem je mu velice podobná a teď zkusíme zapojit více datových typů a všem nastavíme nějakou hodnotu:



	enum enum_Info {

		e_Integer,
		e_String[24],
		Float: e_Float,
		e_Char

	}

	new
		e_Enum[enum_Info];

	sscanf("10 Ahoj 12.33 c", "e<is[24]fc>", e_Enum);
	printf("%i %.2f %s %c", e_Enum[e_Integer], e_Enum[e_Float], e_Enum[e_String], e_Enum[e_Char]);
	/* Vypíše 10 12.33 Ahoj c */

Velké specifikátory

V případě, že vložíme prázdný řetězec(či neúplný), můžeme mu při rozdělení přidat i tzv. "defaultní hodnoty", které pak dosadí, nejjednodušší příklad:

  • Integer
	new
	    Cislo;
	sscanf("", "I(10)", Cislo);
	printf("%i", Cislo); /* Vypíše 10 */

Specifikátor se značí písmenkem I nebo D. Jak si můžeme všimnout, sscanf dostal prázdný řetězec na rozdělení. Tak jak je možné, že se nám do konzole odešle 10? Je to prosté: U specifikátorů datových typů, jsme zaměnili malé i za velké I, což je znamení pro sscanf, že v případě, že tam hodnotou nenajde v řetězci, ať tam doplní jinou, a ta hodnota se přidává do kulatých závorek (). Samozřejmě, lze nastavit defaultní hodnoty i více prom. například:



	new
	    Cislo1, Cislo2;
	sscanf("", "I(10)I(20)", Cislo1, Cislo2);
	printf("%i %i", Cislo1, Cislo2); /* Vypíše 10 20 */
  • String

Specifikátor se značí písmenkem S. Tady je to zajímavější, jelikož defaultní hodnotu u stringu nemusíme psát do uvozovek:



	new
	    String[4 + 1];
	sscanf("", "S(Ahoj)", String);
	print(String); /* Vypíše */

Samozřejmě nesmíme zapomenout na délku stringu, jelikož nám to hodí varování. Doplňujeme zásadně až za defaultní hodnotou:




	new
	    String[4 + 1];
	sscanf("", "S(Ahoj)[5]", String);
	print(String); /* Vypíše Ahoj */
  • Pole

Specifikátor se značí písmenkem A<>. Ani tady není extra rozdíl. Může se hodit při doplňování hodnot, například:



	new
	    Pole[3];
	sscanf("1 2", "A<i>(3)[3]", Pole);
	printf("%i %i %i", Pole[0], Pole[1], Pole[2]); /* Vypíše 1 2 3 */

Všimněte si ale, že nesmíme přepsat specifikátor integeru, v poli na velké písmenko ale musíme celé pole. I tady je funkčnost jednoduchá. Pole, které jsme si deklarovali má 3 prvky. My mu ale doplníme jenom 2. Díky velkému písmenku A informujeme sscanf, že tam nebudou všechny údaje, a tak poslednímu ať defaultně přiřadí hodnotu 3. A co, když tam nebudou například 2? Postup je stále stejný:



	sscanf("1", "A<i>(1, 2)[3]", Pole);

A jak postup, tak výsledek bude stejný. Sscanf dostane na rozdělení pouze jeden údaj ze 3, které mají být správně v poli, a tak vezme defaulní hodnoty a doplní je. Ale co, když nastavíme defaulní hodnotu pouze 1 na 2 chybějící prvky?:



	sscanf("1", "A<i>(2)[3]", Pole);

Tady sscanf nemá moc na vybranou. I když jeho primárním cílem bude doplnit všechny hodnoty do pole, dostane jen jednu defaultní, a zapracuje velice zajímavě: vezme tu jedinou defaultní a doplní je do všech prvků v poli, takže ve výsledku se nám do konzole vypíše 1 2 2

  • Enum

Specifikátor se značí písmenkem E<>. Tady je problém, že uživatel ne jen, že musí přidávat všechny specifikátory ve výčtu, ale také ještě v případě práce s defaultními hodnotami v enumu musí vypsat k každému údaji defaultní hodnotu, i když už nějakou má, například:



	sscanf("11", "E<iii>(11, 22, 33)", epromenna);
	printf("%i %i %i", epromenna[e_cislo], epromenna[e_cislo2], epromenna[e_cislo3]);
	/* Vypíše 11 22 33 */

Jak si můžete všimnout, v řetězci je 11, ale stejně jí musíme přidat do defaultních hodnot. Na závěr kapitoli něco trošku těžšího:



	sscanf("", "E<s[5]fs[6]ii>(Ahoj, 11.2, Scydo, 11, 22)", epromenna);
	print(epromenna[e_String]);
	printf("%.1f", epromenna[e_Float]);
	print(epromenna[e_String2]);
	printf("%i", epromenna[e_Integer]);
	printf("%i", epromenna[e_Integer2]);
	/*
		Vypíše:
	Ahoj
	11.2
	Scydo
	11
	22

	*/

Použití

  • Změnit hráčovi počet životů
Spoiler
  • Zabanovat hráče s důvodem
Spoiler
  • Nahrát více údajů v jednom souboru
Spoiler


Download

To už je složitější, jelikož i když se vydala nová verze, spousty uživatelů hlásí, že buď je tam něco nefunkční a nebo samotná verze nefunguje. Proto jsem vám pro jistotu nahrál verzi sscanfu, kterou používám já a použil jsem ho i na kódy v tomto návodě, a je plně funkční:
https://uloz.to/!vV4WzRFEG/sscanf2-zip



Ihned na začátek zdrojového kódu samozřejmě nesmíte zapomenou sscanf vůbec nahrávat:
 

#include <sscanf2>

A do konfigurace serveru do řádku pro nahrávání pluginů na Windows vepíšete:



plugins sscanf

V případě Linuxu:



plugins sscanf.so

Závěr
Naschvál jsem vynechal spousty ještě dodatků v sscanf2, například "quite" stringy, jelikož nevidím moc lidí, co by to tady využívalo.
A na závěr bych chtěl dodat, že některá teoretická vysvětlení se mohou zdát neúplná, pozměněná a nebo trošku špatná. Důvodem je, že zcela správnÁ vysvětlení by prostý začátečník nebo i čtenář nepochopil. Samozřejmě, pokud mám některé hrubější chybu v kódě nebo v teorii, jak mi napište.

 

[success='Ověřený návod']Tento návod prošel validací, a lze ho proto považovat za ověřený.[/success]


  • 4

#2
vEnd

vEnd

    Programátor apod.

  • Globální moderátor
  • Příspěvků: 421
  • Je tu celkem: 33d 20h 30m 23s

Solidní návod, i já jsem se něčemu přiučil (nikdy jsem nedělal s pluginovou verzí). Ověřeno a přesunuto.


  • 0

96b259ac47244701b5097887d9439120.png

I always enjoy meeting people more chemically imbalanced than myself. -Trevor Philips
Roses are gay, violets are gayer, fuck the poem and listen to Slayer.

Roses are red. Violets are blue. When I Listen to Metallica My neighbors do too!

Unix is user friendly. It just happens to be very selective about who it decides to make friends with.

What's the object-oriented way to become wealthy? Inheritance.


#3
Paulee

Paulee

    Learning pawn ...

  • Uživatel
  • Příspěvků: 576

Steam Profile

  • Paulee - Offline
    Since: led 18 2017 21:46:05
    17,1 hrs last 2 weeks.
    Add Friend

   
  • Je tu celkem: 7d 19h 4m 19s

Dost dobrý návod. Vše krásně rozepsané a srozumitelné. Určitě pokračuj s dalšími návody. GJ


  • 0

Gamenice.sk - My Game My Life


#4
Matus.Cernava

Matus.Cernava

    CMatus

  • Uživatel
  • Příspěvků: 183
  • Je tu celkem: 18d 12h 37m 22s

Ďalší skvelí a prešpekulovaný tutoriál. Hádam na to nováčikovia narazia a budú ho používať tak ako majú. Tiež si vypomohol väčšej časti ktorá nevie anglicky tím pádom čo nie je na pawno.cz ako by neexistovalo. 
Dúfam že budeš písať ďalšie návody do budúcna a budu rovnako skvelo popísané ako dnes. 
Na záver môžem dodať " Len tak ďalej ". 

ps. Vďaka za spomenutie parametru r. 


  • 1





Také označeno jedním nebo více klíčovými slovy: Návod, Scydo, SkiBig18, Y_Less, sscanf2, sscanf, params, parametry

0 uživatelů si prohlíží toto fórum

0 uživatelů, 0 návštěvníků 0 anonymních uživatelů

© 2015 IPS, Inc.

TOPlist

Zajímat Vás mohou ještě aktuální zprávy. sleviště, slevy dnes Herbalife je skvělou cestou pro dobré zdraví. Je libo dětský web?