GTA Közösség - A magyar GTA fórum

San Andreas Multiplayer (SA-MP) => SA-MP: Szerverfejlesztés => Tanuljunk PAWN nyelvet => A témát indította: tonyo - 2009. április 17. - 15:51:05

Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. április 17. - 15:51:05
Na visszatértem, gondoltam írok egy tutorialt.
Egyszer már írt valak iegy tutorialt a fájlokról, de azt én nem találtam elég részletesnek, ezért írok egy újat.Na kezdjük is.
Na most sokan úgy hiszik, h fájlok már elavultak, és msot csak mysql és egyéb adatbázisok a hasznosak...pedig ez nem így van, pl. otthoni szerókhoz nem könnyû ingyen SQL tárhelyt szerezni, és a fájlos megoldás, az ugyan lassabb, de szerintem megbízhatóbb, és könnyen kezelhetõbb(manuálisan).
Mire is jó egy fájl: adatokat tárolhatunk benne. Itt ne csak a regisztrációs rendszer féle adatok jussanak eszetekbe, mint pl. pénz, rp szeróknál lvl és egyebek, hanem pl. autókhoz koordináták, melyek a gamemode indulásakor a fájlban lévõ koordinátákra töltõdnek be, pickup koordináták...
Na most a fájlkezelési függvényeket az file.inc tartalmazza, úgyhogy fájlokkal dolgozáskor ezt kell elõször beágyaznunk a modunkba/scriptünkbe.
 
#include < file >

 
Na most a fájlkezeléshez elõször is meg kell nyitnunk a fájlt. Ehhez az fopen függvényt használjuk fel.
Az fopen függvénynek 2 paramétert lehet megadni, de a 2. elhanyagolható.
1. paraméter: a fájl neve. Ezt tárolhatjuk változóban, lehet konstans, vagy simán csak megadhatjuk \" \"-ek közé írva.
2. paraméter a megnyitás tipusa. Ez attól függ, hogy mit szeretnénk csinálni a fájllal Ez 4 féle lehet:
a) io_write - törli a fájl tartalmát, így ha megnyitod io_write-val, és elmentesz bele egy koordinátát, akk elõtte akármi volt benne, csak ez az egy koordináta marad.
b) io_append - hozzáad egy sort a fájlhoz, tehát az elõzõ adatok is megmaradnak
c) io_read - csak olvasni tudjuk a fájlt
d) io_readwrite - olvashatjuk vagy létrehozhatunk egy újat
Na most akkor így nézhetnek ki egy fájl megnyitása:
 
fopen(\"fájlnév\", io_write);
fopen(\"fájlnév\", io_append);
fopen(\"fájlnév\", io_read);
fopen(\"fájlnév\", io_readwrite);

 
Na most ha a fájl nevét tárolni szeretnénk egy változóban, akkor a változónak a File: -elõtagot kell adnunk.pl:
 
new File: file
file = fopen(\"fájlnév\", io_read);

 
Na most továbbá adatot a fwrite függvénnyel írhatunk egy fájl-ba.
Az fwrite függvény szintén 2 paramétert vár:
1. a fájl azonosítója(ezért célszerû elmenteni pl. egy file nevû változóba)
2. a beírni kívánt szöveget. Mivel file-ban nem általános szöveget akarunk tárolni, hanem általában változó dolgokat, íg ezt általában nem \" \" közé írjuk, hanem formázzuk, mielõtt beírnánk. na egy pl.
 
new szoveg[128] = \"próba\" ;
fwrite(file, szoveg);

 
Na msot a megnyitásnál volt ugyebár olyan h io_append és h io_write, ez dönti el, h hozzáadja, vagy töröl, majd beleír a fájlba az fwrite függvény.
Az adat kiolvasásához az fread függvényt használjuk. Ennek több paramétere is van, de elég mindössze 2-t megadni:
1. paraméter: a fájl azonosítója
2. paraméter: egy szövegváltozó, melybe eltárolhatja az adatokat
 
new string[256];
fread(file, string);

 
Az fread függvény mindig csak 1 sort olvas ki, ezért többszöri meghívás esetén tudjuk kiolvasni az összes sort(ha a sorokat elválasztottuk \\n-nel vagy manuálisan enterrel).
A következõ függvény az fclose függvény. Ha végeztünk, akkor ezzel a függvénnyel \"zárhatjuk\" be a fájlt. Illetve ha egy fájlba több adatot szeretnénk elmenteni, ugy hogy az elõzõeket felülírja, akkor szükségünk lesz erre a függvényre sûrûn.
az fclose mindössze egy paramétert kér: a megnyitott file azonosítója
 
fclose(file);

 
Ezen kívül még vannak pár függvény, amit biztosít a file.inc, de többnyire ezt a 4-et használjuk.
Na akkor nézzünk egy teljes példát. 2 függvényt fogok írni, az egyik kiolvas, a másik betölt egy fájlból adatokat.
egy néhány alap dolog,h ha vki felhasználná, akk mûködjön is neki:
 
enum vEnum
{
PosX,
PosY,
PosZ,
z_Angle
};
new VehInfo[100][vEnum];

 
Na akk a fájlból betöltõ:
 
public LoadVehicle()
{
new strFromFile[34][64];//egy tömb az ideiglenes tároláshoz
new strFromFile2[256];//ide olvassuk ki a szöveget
new File: file = fopen(\"veh.cfg\", io_read);//megnyitjuk olvasásra
if (file)//ha sikerült emgnyitni
{
new idx;//segédváltozó
while (idx < sizeof(VehInfo))//ha kisebb mint 100 akk olvasunk
{
   fread(file, strFromFile2);//olvasunk egy sort
   split(strFromFile2, strFromFile, \',\');//szétdaraboljuk egy tömbbe
   VehInfo[idx][PosX] = floatstr(strFromFile[0]);//feltöltjük az adatokat
   VehInfo[idx][PosY] = floatstr(strFromFile[1]);
   VehInfo[idx][PosZ] = floatstr(strFromFile[2]);
   VehInfo[idx][z_Angle] = floatstr(strFromFile[3]);
   idx++;//segédváltozó növelése
}
fclose(file);//ha 100-at elértük, akk bezárjuk
}
return 1;
}

 
Na msot a mentõ:
 

public SaveVehicle()
{
    new idx;//ismét segédváltozó
new File: file2;//fájl azonosító
while (idx < sizeof(VehInfo))//addig írunk, amég van mit
{
new string[256];//változó a szövegnek
format(string, sizeof(string), \"%f,%f,%f,%f\\n\", VehInfo[idx][PosX], VehInfo[idx][PosY], VehInfo[idx][PosZ], VehInfo[idx][z_Angle]);//formázás
if(idx == 0)//ha az elsõ autó koordinátái
{
   file2 = fopen(\"houseveh.cfg\", io_write);//akk írjuk
}
else
{
   file2 = fopen(\"houseveh.cfg\", io_append);//ha nem, akk hozzáadjuk
}
fwrite(file2, coordsstring);//beleírjuk
idx++;//segédv növelése
fclose(file2);//bezárás
}
return 1;//visszatérés a modba
}

 
Remélem segít valamit, ha kérdésetek van, írjatok.:-D Üdv újra mindenki(nem tom kik emlékeznek még rám)
Nem próbáltam ki, de elvileg mûködnie kell.h mire is jó? hát random kocsikat tehetsz megadott koordinátákra...elvégre ha mindig u.a. a kocsi van ugyanott, az egy idõ után már uncsi.
Cím: [ Leírás ]Fájlok kezelése
Írta: Epsilon - 2009. április 17. - 16:43:59
Szép! Grat.
Epsilon
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. április 17. - 16:52:32
Kösz, láttam már munkáidat, azok is szépek:)
Cím: [ Leírás ]Fájlok kezelése
Írta: Epsilon - 2009. április 17. - 16:59:54
Bár ez off azért kössz :)
Epsilon
Cím: [ Leírás ]Fájlok kezelése
Írta: shanyi - 2009. június 02. - 21:27:57
Sziasztok! Jó rég nem írt ide senki,de én most feltámasztom a témát,na szóval írtam egy \"Kill-Log írót\",de nem úgy mûködik ahogy szeretném,itt is van:
 

new File: KillLog;
public OnPlayerDeath(playerid, killerid, reason)
{
KillLog = fopen(\"killlog.txt\",io_append);
new pName[MAX_PLAYER_NAME],kName[MAX_PLAYER_NAME];
new string[256];
GetPlayerName(playerid, pName, sizeof(pName));
GetPlayerName(playerid, kName, sizeof(kName));
format(string, sizeof(string), \" %s meghalt %s jóvoltából\", pName,kName);
SendClientMessageToAll(COLOR_RED, string);
new logstr[128],ev,honap,nap,ora,perc,masodperc;
getdate(ev, honap, nap);
gettime(ora,perc,masodperc);
format(logstr, sizeof(logstr), \"%i/%i/%i , %i/%i/%i : %s killed %s\\n\", pName,kName,ev, honap, nap,ora,perc,masodperc);
fwrite(KillLog,logstr);
fclose(KillLog);
return 1;
}

 
Annyi a bajom vele,hogy odaírtam hogy \"\\n\",de nem új sorba kezdi az írást,és a nevek helyére \"kockákat\" tesz..kérlek segítsetek!
Cím: [ Leírás ]Fájlok kezelése
Írta: Gergo1352 - 2009. június 03. - 07:11:26
Próbáld meg, hogy \\n helyett \\n\\r-t írsz.
http://hu.wikipedia.org/wiki/Kocsi_vissza
Cím: [ Leírás ]Fájlok kezelése
Írta: shanyi - 2009. június 03. - 14:58:57
Oké, megnézem, de a \"nevek kikockázása\" ellen nincs valami \"oltóanyag\" ?  :D
Cím: [ Leírás ]Fájlok kezelése
Írta: Iceaac - 2009. október 03. - 23:15:56
Hát nekem nem megy a dolog :D Hiába csinálom jól, ahogy kell, mikor beírom a parancsot hibaüzenet nélkül kifagy.
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. október 04. - 10:20:55
Idézetet írta: shanyi date=1243970877\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"24\" data-ipsquote-contentclass=\"forums_Topic
Sziasztok! Jó rég nem írt ide senki,de én most feltámasztom a témát,na szóval írtam egy \"Kill-Log írót\",de nem úgy mûködik ahogy szeretném,itt is van:
 

new File: KillLog;
public OnPlayerDeath(playerid, killerid, reason)
{
KillLog = fopen(\"killlog.txt\",io_append);
new pName[MAX_PLAYER_NAME],kName[MAX_PLAYER_NAME];
new string[256];
GetPlayerName(playerid, pName, sizeof(pName));
GetPlayerName(playerid, kName, sizeof(kName));
format(string, sizeof(string), \" %s meghalt %s jóvoltából\", pName,kName);
SendClientMessageToAll(COLOR_RED, string);
new logstr[128],ev,honap,nap,ora,perc,masodperc;
getdate(ev, honap, nap);
gettime(ora,perc,masodperc);
format(logstr, sizeof(logstr), \"%i/%i/%i , %i/%i/%i : %s killed %s\\n\", pName,kName,ev, honap, nap,ora,perc,masodperc);
fwrite(KillLog,logstr);
fclose(KillLog);
return 1;
}

 
Annyi a bajom vele,hogy odaírtam hogy \"\\n\",de nem új sorba kezdi az írást,és a nevek helyére \"kockákat\" tesz..kérlek segítsetek!
 
Gyors beleolvasásra 1 dolog tûnt fel:
 
GetPlayerName(playerid, pName, sizeof(pName));
GetPlayerName(playerid, kName, sizeof(kName));

 
Megölte magát?:D a 2.-nál én inkább killerid-t írnék, a playerid helyett. De sztem nem ez vele a problémád, ha lesz idõm, elolvasom, és megoldjuk;)
------------------------------------------------------------------------------
Edit: Na asszem megtaláltam a hibát, kijavított, mûködõképes változat:
 
new File: KillLog;
public OnPlayerDeath(playerid, killerid, reason)
{
KillLog = fopen(\"killlog.txt\",io_append);
new pName[MAX_PLAYER_NAME], kName[MAX_PLAYER_NAME], string[256], ev,honap,nap,ora,perc,masodperc;
getdate(ev, honap, nap);
gettime(ora,perc,masodperc);
GetPlayerName(playerid, pName, sizeof(pName));
GetPlayerName(killerid, kName, sizeof(kName));
format(string, sizeof(string), \" %s meghalt %s jóvoltából\", pName,kName);
SendClientMessageToAll(COLOR_RED, string);
format(string, sizeof(string), \"%i/%i/%i , %i/:%i/:%i : %s killed %s\\n\", ev, honap, nap, ora, perc, masodperc ,pName ,kName);
fwrite(KillLog,string);
fclose(KillLog);
return 1;
}

 
Tesztelni nem tudom, mert nincs fent SA most még, de elméletileg mûködnie kell.
A hiba, ami miatt nem a nevet írta, az az volt, hogy %i-vel kezdted, és a végére tettél %s-t, viszont a string változót elõre tetted. Ezért nem írta a nevet. A másik, a meghalt játékos neve 2x volt lekérve, a gyilkosé egyszer sem. Mind2 dolgot javítottam, a logstr változót töröltem, helyette 2x használtam a stringet, ill. kicsit módosítottam a sorrendet, de az lényegtelen, csak én így szeretem:D na remélem segítettem. Ha valaki letesztelné, megköszönném.
Cím: [ Leírás ]Fájlok kezelése
Írta: Iceaac - 2009. október 04. - 18:14:23
Angol fórumon láttam Dinihez tutorialt, és azzal megy :D
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. október 05. - 15:58:22
Én személy szerint gyûlölöm a dinit, meg ehhez hasonlókat... lehet hogy meggyorsítja a munkát, de én jobb szeretem saját magamnak megírni a dolgokat. Am havernál kipróbáltuk, ott jó volt. De ha már megcsináltad máshogy, akk használja egészséggel aki akarja:D
Cím: [ Leírás ]Fájlok kezelése
Írta: Iceaac - 2009. október 06. - 06:48:02
Idézetet írta: Anthony date=1254751102\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"24\" data-ipsquote-contentclass=\"forums_Topic
Én személy szerint gyûlölöm a dinit, meg ehhez hasonlókat... lehet hogy meggyorsítja a munkát, de én jobb szeretem saját magamnak megírni a dolgokat. Am havernál kipróbáltuk, ott jó volt. De ha már megcsináltad máshogy, akk használja egészséggel aki akarja:D
 
Jah és ilyen nincs file.incben:
 
dini_Create(filename[])
dini_Remove(filename[])

 
 ;)
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. október 06. - 14:45:09
fremove függvényre gondolsz? mert az van. A másik pedig eleve hülyeség, mert ha írásra nyitsz meg egy fájlt, akkor automatikusan létrehozza, ha még nincs, ha jól tudom, ha nem javítsatok ki.
Cím: [ Leírás ]Fájlok kezelése
Írta: Robinking - 2009. október 06. - 19:13:06
Jó lett, grat.
Csak kicsit nehéz felfogni, de ha nagyon akar az ember bármit  elérhet :D
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. október 06. - 19:56:27
Robinking: Semmi sem nehéz, max. elsõ olvasásra nem sok marad meg. De nem olyan bonyolult. De én mindig arra esküszöm, hogy nem elég az elmélet, nem árt hozzá nézni 1-2 nagyobb és ismertebb mod-ból példákat nézni, azzal válik igazán érthetõvé.
/OFF: Csak nekem tûnik, h kicsit HSZ vadászatot játszol? ;D
Cím: [ Leírás ]Fájlok kezelése
Írta: Robinking - 2009. október 06. - 20:15:43
Idézetet írta: Anthony date=1254851787\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"24\" data-ipsquote-contentclass=\"forums_Topic
Robinking: Semmi sem nehéz, max. elsõ olvasásra nem sok marad meg. De nem olyan bonyolult. De én mindig arra esküszöm, hogy nem elég az elmélet, nem árt hozzá nézni 1-2 nagyobb és ismertebb mod-ból példákat nézni, azzal válik igazán érthetõvé.
/OFF: Csak nekem tûnik, h kicsit HSZ vadászatot játszol? ;D
 
õõõ, nem igazán tudom, hogy mit jelent.
Cím: [ Leírás ]Fájlok kezelése
Írta: Iceaac - 2009. október 06. - 20:22:46
Dini jobb mint a file.inc és ennyi :D
OFF: Sztem is HSZ vadász.
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. október 06. - 20:28:08
ízlések és pofonok...
Cím: [ Leírás ]Fájlok kezelése
Írta: ZeRo - 2009. október 06. - 20:30:54
A fájlírás \'hagyományos\', és tényleg jól bevált dolog. A dini is elég jó, de azt nem szabad a fájlírással összehasonlítani, ugyanis szerintem a dini - t inkább regisztrációs rendszerekben használják. De ha már itt tartunk, abban a kategóriában az adatbáziskezelés verhetetlen ( MySQL ). :P
ZeRo
Cím: [ Leírás ]Fájlok kezelése
Írta: Robinking - 2009. október 06. - 20:45:11
OFF: Nem vagyok HSZ vadász csak szeretem megmondani a véleményemet.
És tudom, hoy milyen jó érzés, amikor azt mondják a munkádra, hogy gratulálok, szép lett.
Cím: [ Leírás ]Fájlok kezelése
Írta: Woozie - 2009. november 07. - 18:08:35
Párszor átolvastam , de nem sokat értettem meg belole.

Amit szerettem volna nem lehetséges, szerintem.


Még átolvasom párszor  :D
Cím: [ Leírás ]Fájlok kezelése
Írta: tonyo - 2009. november 12. - 14:43:06
Mit szeretnél?:D