Kubko 22 Odesláno: 2. Červen, 2014 Share Odesláno: 2. Červen, 2014 (upraveno) 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ý argumentUkáž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ý argumentbool:pack = false - Má byť použitý "pack" stringu? *Volitelný argumentUpozornenie! - 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 MSAko 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 MSTu 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á: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 17. Duben, 2015 by VolfikCŽ 2 Link to comment Share on other sites More sharing options...
ATomas 286 Odesláno: 2. Červen, 2014 Share Odesláno: 2. Červen, 2014 Dobry navod. A hlavne se mi libi ze taky nekdo prisel nato ze ty includy zatezuji jako prase 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 More sharing options...
Kubko 22 Odesláno: 2. Červen, 2014 Author Share Odesláno: 2. Červen, 2014 Dobry navod. A hlavne se mi libi ze taky nekdo prisel nato ze ty includy zatezuji jako prase 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now