Jump to content

návod Práca so súbormi [**]


Kubko

Recommended Posts

Práca so súbormi

 

Obtiažnosť - * * * * *

Vitajte pri mojom prvom návode pre pawn. Dnes Vám ukážem niečo o práci so súbormi použitím includu "file". Tento include obsahuje funkcie, ktoré nám budú umožňovať pracovať so súbormi. Môžeme do nich zapisovať údaje, čítať údaje a omnoho viac. Mnohí z Vás pre toto používate tzv. "INI" includy, ktoré plnia tú istú úlohu, ale k tomuto sa dostaneme ešte neskôr. Čítajte prosím s porozumením!

Otvorenie a zatvorenie súboru:

Súbor otvoríme pomocou funkcie fopen, ktorá vráti tzv. "file handle" súboru, s ktorým budeme pracovať. Ak nastane nejaká chyba, táto funkcia vráti hodnotu 0. Súbor je vždy potrebné na konci zavrieť funkciou fclose!

Argumenty (fopen):

name[] - Umiestnenie súboru s jeho príponou na konci, ktorý sa nachádza v priečinku "scriptfiles".
mode - Mód, ktorý určuje, ako budeme pracovať so samotným súborom. Viď všetky typy módov nižšie.

Typy módov:

io_read - Pre čítanie zo súboru.
io_write - Pre zápis do súboru, vytvorí súbor, vymaže celý jeho obsah!
io_readwrite - Pre čítanie aj zápis do súboru, ak súbor neexistuje vytvorí ho.
io_append - Pre zápis na koniec súboru.

Argumenty (fclose):

File:handle - Ako ste sa mohli dočítať vyššie, je to premenná v ktorej je uložený "handle" súboru.

Ukážka:



new File:subor = fopen("subor.txt", io_readwrite);
if (subor)
{
	//Tu budeme pracovať so súborom.
	fclose(subor);
} 

Otvorili sme súbor "subor.txt" v priečinku scriptfiles, pomocou módu io_readwrite. Potom sme pridali podmienku ak nenastala chyba pri otváraní súboru (ak by nastala chyba premenná by mala hodnotu 0). Ďalej už len budeme pracovať so samotným súborom. Na konci sme súbor zavreli, čím sa zapísaný obsah uložil.

Zápis do súboru:

Na zápis do súboru použijeme funkciu fwrite, ktorá zapíše do nášho súboru celý riadok ako string. Pokiaľ chcete vpísať do súboru znaky s diakritiou je tu druhá varianta, použitie funkcie fputchar. Je však o niečo pomalšia v rýchlosti ako prvá varianta.

Argumenty (fwrite):

File:handle - "Handle" súboru, do ktorého chceme vykonať zápis.
string[] - String, ktorý chceme do súboru zapísať.

Argumenty (fputchar):

File:handle - "Handle" súboru, do ktorého chceme vpísať znak.
value - Znak ktorý chcete vpísať, môže to byť ASCII, alebo UTF-8 hodnota.
bool:utf8 = true - Má byť znak vpísaný ako UTF-8? (použite false, pokiaľ chcete vpísať znak s diakritikou) *Volitelný argument

Ukážka:

new File:subor = fopen("subor.txt", io_write);
if (subor)
{
	fwrite(subor, "Toto je string, ktory zapisujem do mojho suboru!");
	fclose(subor);
}

Otvorili sme súbor a zapisáli do neho text, nakoniec sme ho zatvorili.

Ukážka č.2:

new File:subor = fopen("subor.txt", io_write);
if (subor)
{
    new string[7] = "Sanios";
    for (new i; i < sizeof (string); i++)
    {
        fputchar(subor, string[i]);
    }
    fclose(subor);
}

Otvorili sme súbor a vpísali do neho text, znak po znaku, nakoniec sme ho zatvorili.

Čítanie zo súboru:

Pre čítanie údajov zo súboru môžme taktiež použiť dve varianty. Tá prvá je použitím funkcie fread, ktorá prečíta celý riadok zo súboru a uloží ho do stringu. Tá druhá varianta je čítanie znak po znaku, za pomoci funkcie fgetchar?. Táto varianta má svoju výhodu, ale aj nevýhodu. Tá výhoda je, že obsahuje argument "utf8", ktorý nám umožňuje prečítať taktiež znaky s diakritikou. Funkcia vráti ASCII, alebo UTF-8 hodnotu. Nevýhoda je, že je to o niečo pomalšie, ako funkcia fread, ktorá prečíta celý riadok.

Argumenty (fread):

File:handle - "Handle" súboru, z ktorého chceme čítať
string[] - String, do ktorého chceme prečítaný text z riadka uložiť.
size = sizeof string - Počet polí stringu, do ktorého ukladáme text. *Volitelný argument
bool:pack = false - Má byť použitý "pack" stringu? *Volitelný argument

Upozornenie! - Pozri si tiež na konci odsek "Možné chyby a ich oprava"!

Argumenty (fgetchar):

File:handle - "Handle" súboru, z ktorého chceme čítať
bool:utf8 - Má byť znak prečítaný ako UTF-8? (použite false, pokiaľ chcete prečítať znak s diakritikou)

Ukážka:

new File:subor = fopen("subor.txt", io_read);
if (subor)
{
    new string[128];
    fread(subor, string);
    printf("String: %s\nPrvý znak stringu je %c", string, fgetchar(subor, false));
    fclose(subor);
}

Otvorili sme súbor s módom pre čítanie, prečítali sme z neho riadok a prečítaný string sme vypísali v konzole servera spoločne so začiatočným znakom riadku, nakoniec sme súbor zatvorili.

Porovnanie s "INI" includmi:

Určite mnohí z Vás používate na prácu so súbormi nejaké "INI" includy, ako je "y_ini", "DOF2", alebo "dini". Určite si kladiete otázku, prečo používať základné funkcie, keď mám rýchlejší includ. Toto nie je pravda. "INI" súbor má svoju výhodu v tom, že zapisuje riadky v tvare "name=value", resp. "key=value". To znamená, že výhodou je určite prehľadnosť vo Vašom súbore a vždy budete vedieť, ktorá hodnota k čomu patrí. Samozrejme výhodou includu "file" je predovšetkým rýchlosť! Pripravil som si pár testov rýchlosti o zápise a čítaní zo súboru.

Testy

Zápis:

Zápis 10 znakového riadku do súboru (pod sebou 1000x):
"dini" - 1521 MS
"file" - 2 MS
"y_ini" - 6 MS
Ako vidíte, najrýchlejšie sa s tým vysporiadal náš includ "file", samozrejme, že sa nezahanbil ani "y_ini". Includ "dini" podal najslabší výsledok, trvalo mu to niečo cez sekundu a pol.


Čítanie:

Čítanie 15 znakového riadku (pod sebou 1500x):
"dini" - 10547 MS
"file" - 6 MS
"y_ini" - 1991 MS
Tu môžeme vidieť znova víťazí includ "file", "y_ini" podal tiež pomerne slušný výkon.


(Pridám viacej testovaní ešte neskôr, ak by ste chceli nejaký konkrétny test kľudne mi napíšte.)



Možné chyby a ich oprava:

V tejto sekcii Vám napíšem niečo o možných chybách, ktoré môžu nastať. Nájdete tu pochopiteľne aj samotnú opravu chyby.

1. Funkcia strcmp nevráti hodnotu 0, pretože stringy sa nezhodujú:

Toto je dosť častá chyba. Nastane vtedy keď ste prečítali obsah riadka pomocou funkcie fread. Prečo sa teda stringy nezhodujú, keď sú v súbore zapísané správne? Pretože na konci súboru ostali dva znaky "\r\n". Tieto znaky vyjadrujú, že sa jedná o nový riadok. Nachádzajú sa na konci každého riadku, okrem posledného.

Pre inšpiráciu ako to v skutočnosti vyzerá:
zshpjwlttdhdvlltnx2.png

Oprava:

new File:subor = fopen("subor.txt", io_read);
if (subor)
{
    new string[128];
    fread(subor, string); //Prečítali sme riadok a na konci máme dva znaky "\r\n".
    strdel(string, strlen(string)-2, strlen(string)); //Vymažeme posledné dva znaky.
}
fclose(subor);

Scripty na ukážku:

Pridám Vám na ukážku aj nejaký scripty, k čomu môžete napríklad includ "file" využiť.

1. Záznam o vraždách:

Tento jednoduchý skript bude v súbore zaznamenávať údaje o vraždách. Do súboru sa zapíše meno obete, meno vraha a dôvod, akým bola obeť usmrtená.

 



public OnPlayerDeath(playerid, killerid, reason)
{
	new forma[128], HracMeno[2][MAX_PLAYER_NAME];
	new const SmrtDovod[][] =
	{
		"Fist",
		"Brass Knuckles",
		"Golf Club",
		"Nightstick",
		"Knife",
		"Baseball Bat",
		"Shovel",
		"Pool Cue",
		"Katana",
		"Chainsaw",
		"Purple Dildo",
		"Dildo",
		"Vibrator",
		"Silver Vibrator",
		"Flowers",
		"Cane",
		"Grenade",
		"Tear Gas",
		"Molotov Cocktail",
		"9mm",
		"Silenced 9mm",
		"Desert Eagle",
		"Shotgun",
		"Sawnoff Shotgun",
		"Combat Shotgun",
		"Micro SMG/Uzi",
		"MP5",
		"AK-47",
		"M4",
		"Tec-9",
		"Country Rifle",
		"Sniper Rifle",
		"RPG",
		"HS Rocket",
		"Flamethrower",
		"Minigun",
		"Satchel Charge",
		"Detonator",
		"Spraycan",
		"Fire Extinguisher",
		"Camera",
		"Night Vis Goggles",
		"Thermal Goggles",
		"Parachute",
		"Fake Pistol",
		"Vehicle",
		"Helicopter Blades",
		"Explosion",
		"Drowned",
		"Splat",
		"Connect",
		"Disconnect"
	};
	GetPlayerName(playerid, HracMeno[0], sizeof (HracMeno[]));
	GetPlayerName(killerid, HracMeno[1], sizeof (HracMeno[]));
	format(forma, sizeof (forma), "Zomrel hrac: %s, bol usmrteny hracom %s. Dovod: %s\r\n", HracMeno[0], HracMeno[1], SmrtDovod[reason]);
	new subor = fopen("subor.txt", io_append);
	fwrite(subor, forma);
	fclose(subor);
	return 1;
} 

 

 

 

Návod označen jako platný

Ten to návod byl označen jako platný.Návod může být kdykoli označen jako nevhodný či neplatný

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

Dobry navod. A hlavne se mi libi ze taky nekdo prisel nato ze ty includy zatezuji jako prase :d

A jen takovy detail. fread vraci true pokud precetl radek a false pokud neprecetl (hodi se to pro precteni celeho obsahu souboru pomoci while)

Link to comment
Share on other sites

Dobry navod. A hlavne se mi libi ze taky nekdo prisel nato ze ty includy zatezuji jako prase :d

A jen takovy detail. fread vraci true pokud precetl radek a false pokud neprecetl (hodi se to pro precteni celeho obsahu souboru pomoci while)

 

Díky, to s tým fread so vysvetlením ako to funguje na čítanie celého súboru, chcem ešte pridať. 

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...