Using Files to write data/values(old and new file commands)
Posted: Fri Sep 25, 2026 4:49 am
This is a little tutorial about reading/writing files to store something.
This Tutorial need basics in Amxx Scripting.
I am not so good in explain and writing Tutorials,so the most are writing as code.
I dont explain every Command.
If there something wrong or better please post.
Lets begin with the old file commands (easy and short).
Read a specific line with given lenght into an array.
It returns index of next line or 0 when the end of the file is reached.
The number of characters read is stored in txtLen.
Write an array to file to the given line,if line is -1 it write at end of the file
The next are the new file commands(many and very powerfull)
Lets begin with basics of new file commands and write/read a string inside a file.
This is good for textfiles where easily can read the file
The new file commands dont read linespecific,they use a cursor inside the file to read the data.
This cursor position can get with
And the cursor can set with
"position" is an offset from start
start can be:
move the cursor position to begin of the file.
Open a file with given filename and mode.
It returns a pointer to the file.
Write a string to a text file at current filecursor position.
"file" must be a pointer to a file from the fopen command.
Write a formated string to a text file.Same as the format/formatex command,but for files.
fputs/fprint dont add a newline at end of the string,so it must set manually.
Read a line (including newlines) from a text file from current filecursor position until maxlenght is reached or newline/end of file is founded.
To write a file where must save many data ,the plugin growing big and are many work to write with using Parse,str_to_,...
Here a little trick that i have learn to use strucs in Pawn.
This is very easy to manage the filedata and adding new data,but every change need to change/convert also the file.
enum give the variable inside the {} a number.It begin with number 0.
With "new variablename[enumname]" it create a variable with the arraylenght of the given enum.
Write an array to the file at current cursor position."blocksize" is the size of the array or the lenght who want to write.
Mode can be:
Reads blocknum blocks from a file at current file cursor position until blocksize is reached or end of the file is found.It returns the number of succesfully readed blocks.
I hope i can help some with this little tutorial.
At the end i add the final Plugin that can be used as core to write/read data from file.
This Tutorial need basics in Amxx Scripting.
I am not so good in explain and writing Tutorials,so the most are writing as code.
I dont explain every Command.
If there something wrong or better please post.
Lets begin with the old file commands (easy and short).
Code: Select all
read_file ( const file[], line, text[], len, &txtLen )It returns index of next line or 0 when the end of the file is reached.
The number of characters read is stored in txtLen.
Code: Select all
write_file ( const file[], const text[], [ line ] )Code: Select all
#include <amxmodx>
#include <amxmisc>
#define PLUGIN "Filehandle"
#define VERSION "1.0"
#define AUTHOR "Administrator"
new filename[256]
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
/*get the config directory of amxx*/
get_configsdir(filename,255)
format(filename,255,"%s/filehandle.txt",filename)
register_concmd("amx_filetestwrite","filewritetest")
register_concmd("amx_filetestread","filereadtest")
}
public filewritetest(id){
new writedata[128]
new steamid[32],name[32],anyvalue,Float:anyfloatvalue
/*Lets create and copy some dummy data*/
get_user_authid(id,steamid,31)
get_user_name(id,name,31)
anyvalue = 10
anyfloatvalue = 5.5
formatex(writedata,127,"%s %s %d %f",steamid,name,anyvalue,anyfloatvalue)
/*Now write this data to the file at last line
write_file ( const file[], const text[], [ line ] )
The line parameter defaults to -1, which appends to the end of the file. Otherwise, a specific line is overwritten.
If no file exist write_file create one*/
write_file(filename,writedata)
}
public filereadtest(id){
new readdata[128],steamid[32],anyvalue,Float:anyfloatvalue,txtlen
new parsedsteamid[32],parsedname[32],parsedanyvalue[8],parsedanyfloatvalue[8]
/*now read the data from the file*/
/*It give 2 ways to read a file until end of line*/
/*The first way*/
/*file_size - Returns the size of a file.
If flag is 0, size is returned in bytes.
If flag is 1, the number of lines is returned.
If flag is 2, 1 is returned if the file ends in a line feed.
If the file doesn't exist, -1 is returned. */
new fsize = file_size(filename,1)
for (new line=0;line<=fsize;line++)
{
/*read_file ( const file[], line, text[], len, &txtLen )*/
read_file(filename,line,readdata,127,txtlen)
/*We must parse the readata in somthing that we can use*/
parse(readdata,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)
/*check if steamid the same as in file*/
get_user_authid(id,steamid,31)
if(equal(steamid,parsedsteamid))
{
/*steamid is same as in file,the do somthing with the rest of parsed values*/
anyvalue = str_to_num(parsedanyvalue)
anyfloatvalue = str_to_float(parsedanyfloatvalue)
client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)
/*i use break to stop the loop to save more performance.On big files this is good*/
break
//...
}
}
/*The second way/the better way*/
new line = 0
while(!read_file(filename,line++,readdata,127,txtlen))
{
parse(filename,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)
get_user_authid(id,steamid,31)
if(equal(steamid,parsedsteamid))
{
anyvalue = str_to_num(parsedanyvalue)
anyfloatvalue = str_to_float(parsedanyfloatvalue)
client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)
break
//...
}
}
}Lets begin with basics of new file commands and write/read a string inside a file.
This is good for textfiles where easily can read the file
The new file commands dont read linespecific,they use a cursor inside the file to read the data.
This cursor position can get with
Code: Select all
ftell(file)Code: Select all
fseek ( file, position, start )start can be:
Code: Select all
SEEK_SET //beginning of the file
SEEK_CUR //current cursor position
SEEK_END //end of the fileCode: Select all
rewind ( file )Code: Select all
fopen ( filename[], mode[] )It returns a pointer to the file.
Code: Select all
fputs ( file, const text[])"file" must be a pointer to a file from the fopen command.
Code: Select all
fprintf ( file, const buffer[], ... )fputs/fprint dont add a newline at end of the string,so it must set manually.
Code: Select all
fgets ( file, buffer[], maxlength )Code: Select all
#include <amxmodx>
#include <amxmisc>
#define PLUGIN "Filehandle"
#define VERSION "1.0"
#define AUTHOR "Administrator"
new filename[256]
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
get_configsdir(filename,255)
format(filename,255,"%s/filehandle.txt",filename)
register_concmd("amx_filetestwrite","filewritetest")
register_concmd("amx_filetestread","filereadtest")
}
public filewritetest(id){
new writedata[128]
new steamid[32],name[32],anyvalue,Float:anyfloatvalue
get_user_authid(id,steamid,31)
get_user_name(id,name,31)
anyvalue = 10
anyfloatvalue = 5.5
/*fopen - Returns a file handle for advanced file functions.
Mode uses the standard C library of mode types.
The first character can be:
"a" - append
"r" - read
"w" - write
The second character can be:
"t" - text
"b" - binary
You can also append a "+" to specify both read and write.
Open a file in append+read+write mode
On mode "a+"/"w+" it create a file if there no exist
Mode "w+" overwrite a file if one exist*/
new filepointer = fopen(filename,"a+")
/*check if file is open,on an error filepointer is 0*/
if(filepointer)
{
/*It give 2 ways to write a string inside a file*/
/*First way*/
formatex(writedata,127,"%s %s %d %f^n",steamid,name,anyvalue,anyfloatvalue)
//The new file commands need to create a newline manual with "^n"
/*write the string to the file*/
/*another commands are:
fputc - Writes a char (1 byte) to a file handle.
fputf - Writes a float (4 bytes, 8 on AMD64) to a file handle.
fputi - Writes an integer (4 bytes) to a file handle.
fputl - Writes a long (4 bytes) to a file handle. */
fputs(filepointer,writedata)
/*Second way*/
/*fprintf - Writes a line to a file */
fprintf(filepointer,"%s %s %d %f^n",steamid,name,anyvalue,anyfloatvalue)
/*close the file,this is optional,but better is it to close the file*/
fclose(filepointer)
}
}
public filereadtest(id){
/*open file in read-mode*/
new filepointer = fopen(filename,"r")
/*check if file is open,on an error filepointer is 0*/
if(filepointer)
{
new readdata[128],steamid[32],anyvalue,Float:anyfloatvalue
new parsedsteamid[32],parsedname[32],parsedanyvalue[8],parsedanyfloatvalue[8]
/*Read the file until it is at end of file*/
/*fgets - Reads a line from a text file -- includes newline!*/
while(fgets(filepointer,readdata,127))
{
parse(readdata,parsedsteamid,31,parsedname,31,parsedanyvalue,7,parsedanyfloatvalue,7)
get_user_authid(id,steamid,31)
if(equal(steamid,parsedsteamid))
{
anyvalue = str_to_num(parsedanyvalue)
anyfloatvalue = str_to_float(parsedanyfloatvalue)
client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",parsedsteamid,parsedname,anyvalue,anyfloatvalue)
break
//...
}
}
fclose(filepointer)
}
}Here a little trick that i have learn to use strucs in Pawn.
This is very easy to manage the filedata and adding new data,but every change need to change/convert also the file.
Code: Select all
enum enumname{}With "new variablename[enumname]" it create a variable with the arraylenght of the given enum.
Code: Select all
fwrite_raw ( file, const stream[], blocksize, mode )Mode can be:
Code: Select all
BLOCK_INT //Good to write any value/char
BLOCK_SHORT //For writing values -32767 -> 32767 and chars
BLOCK_CHAR //Good for writing chars/values -127 -> 127
BLOCK_BYTE //Same as charCode: Select all
fread_raw ( file, stream[], blocksize, blocknum )Code: Select all
#include <amxmodx>
#include <amxmisc>
#define PLUGIN "Filehandle"
#define VERSION "1.0"
#define AUTHOR "Administrator"
new filename[256]
enum PLAYER_DATABASE
{
STEAMID[32],
NAME[32],
ANYVALUE,
ANYFLOATVALUE,
PLAYER_DATABASE_END
}
new player_data[33][PLAYER_DATABASE]
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
get_configsdir(filename,255)
format(filename,255,"%s/filehandle.txt",filename)
register_concmd("amx_filetestwrite","filewritetest")
register_concmd("amx_filetestread","filereadtest")
}
public filewritetest(id){
/*Lets create and copy some dummy data into data*/
get_user_authid(id,player_data[id][STEAMID],31)
get_user_name(id,player_data[id][NAME],31)
player_data[id][ANYVALUE] = 10
/*theres a little problem with enum and floats:player_data[id][ANYFLOATVALUE] = 5.5 return an tag mismatch error
this error can be ignored but a better way is using _: in front of the float value*/
player_data[id][ANYFLOATVALUE] = _:5.5
new fp=fopen(filename,"a+")
if(fp)
{
/*There exist 3 commands
fwrite - Writes an element to a file (for single chars)
fwrite_blocks - Writes a block of data in a file (for unknown,havent get any good results with this)
fwrite_raw - Writes blocks of data to a file (for strings/arrays)*/
fwrite_raw(fp,player_data[id][PLAYER_DATABASE:0],sizeof(player_data[]),BLOCK_INT)
/*Now i explain the fwrite_raw
fp is the filepointer
player_data[id] is the data from player
[PLAYER_DATABASE:0] is the begining of the data who want to write,
to write only Steamid it need to use player_data[id][PLAYER_DATABASE:STEAMID]
sizeof(player_data[]) is the lenght of data which want to write,
to write somthing like only steamid it need "player_data[id][PLAYER_DATABASE:STEAMID],32"
*/
}
fclose(fp)
}
public filereadtest(id){
new readdata[PLAYER_DATABASE],steamid[32]
new fp=fopen(filename,"r")
if(fp)
{
while(fread_raw(fp,readdata[PLAYER_DATABASE:0],sizeof(player_data[]),1))
{
get_user_authid(id,steamid,31)
if(equal(steamid,readdata[STEAMID]))
{
player_data[id][ANYVALUE] = readdata[ANYVALUE]
player_data[id][ANYFLOATVALUE] = _:readdata[ANYFLOATVALUE]
copy(player_data[id][STEAMID],31,readdata[STEAMID])
copy(player_data[id][NAME],31,readdata[NAME])
client_print(id,print_chat,"Your saved Steamid:%s Name:%s Value:%d FloatValue:%f",readdata[STEAMID],readdata[NAME],readdata[ANYVALUE],readdata[ANYFLOATVALUE])
client_print(id,print_chat,"Your saved Data:%s Name:%s Value:%d FloatValue:%f",player_data[id][STEAMID],player_data[id][NAME],player_data[id][ANYVALUE],player_data[id][ANYFLOATVALUE])
break
//...
}
}
}
fclose(fp)
}At the end i add the final Plugin that can be used as core to write/read data from file.