Lua file reading and writing error - file

Sorry if there's already a topic like this, but I couldn't find any that have something to do with Lua... So I'm basically having some problems in writing and reading files, here's what I've done:
hp = 25
file = io.open("player.txt","w")
if file==nil then
io.output("player.txt")
io.close()
end
file:write(hp)
file:close()
and it seems to work fine, it's just perfect... but then when I'm trying to add the file:write(hp) inside the if-sentence, it doesn't work. Also if I'll add file:read("*line") right after file:write(hp), this is what it says in player.txt:
25b[NUL]ÈñZ[NUL]
file = io.open("player.txt","w")
So what am I doing wrong? Also [NUL] is black block with white "NUL" text in it in notepad++ but it can't be copied here.
Edit: Hmmh, seems like the whole code is messed, up it always rewrites the whole file ;o
Edit2: Had actually no idea what I was talking about, nowadays I can understand file controlling bit more, here's what it should've been or what I tried to do:
function existsFile(path)
x = io.open(path)
if x == nil then
io.close()
return false
else
x:close()
return true
end
end
if not existsFile("player.txt") then
file = io.open("player.txt", "w")
file:write(25)
hp = 25
file:close()
else
file = io.open("player.txt", "r")
hp = file:read("*number")
file:close()
end
And I know it doest look anything like the code I first posted, but that's what I basically meant.

Could you explain what you are trying to do in this code?
Why do you need to check if file is nil? When you open file for writing, lua automatically creates it if not exists.
"w" mode means, that you you're erase all data in file and write new data
May be you need "a" mode? In this mode new lines are added at the end of file.

Sounds like you're confused about the flags on io.open. Check the manual to be sure what you really want is the w flag since that overwrites everything.
Trying to do a file:write when you're in the if shouldn't work, and I'm not sure why you'd expect it to, since file is nil. You're saying that if the file couldn't be opened, then try to write this to the file, which doesn't make sense to me.

The "if" block checks if "file" is nil, so that code block will never run.
read() doesn't work because you opened the file in "w" (write) mode.
Erasing the whole file is the expected behavior of write mode. In that mode the file is first erased and then you write new data to it.

Related

Lua 5.2.1 - Edit and save variable in file

I have a file which is part of a game I'm making, and I am trying to manipulate it with code.
Here is the file:
tech =
{
weaponstech = 1.5,
armortech = 1.8,
shieldstech = 2
}
I am trying to open the file like this
local file = io.open("tech")
and then try to change the value of the variable 'shieldstech' to 2.2.
I need this to happen automatically every time I run a function.
I usually use single variable files such as this:
v = 1
but that just gives me a clutter of files which is unmanageable.
so now I store variables the way I wrote my tech file.
This is how I used to edit these single-variable files:
local file = io.open("file", "w")
file:write("v = "..var)
file.close()
but it is just too much work to rewrite the whole file in a single line or code, so I want to just change and save the variable, something like this:
local file = io.open("tech", "w")
shieldstech = 2.2
file:close()
but it won't work like that, and I know why. I'm not telling the program to edit the file, I'm telling it to edit the variable in that instance of the program. All I'm doing to the file is opening it and then closing it.
Any of you guys know a way to do this?
Thx,
Brendan
My suggestion would be to use something designed for that task already. Here is an example: https://github.com/2ion/ini.lua That will allow you to read in the data, make as many or as few changes to it as you want, and then write it back out.
EDIT: This has a dependency on this: https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua
Might want to try inih instead (although it's written C, so integration will require a bit more knowledge): http://luarocks.org/repositories/rocks/#lua-inih
This will rewrite the whole file each time, which is not very performing, but it will work. Consider using a sqlite database.
local file = io.open("tech", "w")
file:write("tech = {")
for p,v in pairs(tech) do file:write(p .. " = " .. v .. "," ) end
file:write("}")
file:close()

Is there a way to clear a file context after you've written data in it?

I have this program where I open a file and write data points in it but the problem is I have to do that inside a loop. it goes:
file1=importdata('myfile.txt','%s')
for k=1:1:128
fid=fopen('myfile2.txt','w+') % I write input to that file and pass it to my exe file
fprintf(fid,'input1')
fprintf(fid,'input2')
fprintf(fid,'input3')
the 4th input (input4) is being taken from a diff file.txt and
input4=sscanf(file1{k},'%s')
Val=str2double(input4)
fprintf(fid,'%.3f',Val)
fclose(fid)
[status,result]=system('command<myfile2.txt')
M= sscanf(result,'%s')
more_result=[ Val M]
Fid2=fopen(myfile3.txt,'w+')
frpintf(Fid2,'%s', more_result)
end
This is a vague idea of the code.
Then I sscanf the results to get the a specific value (M) that I want.
I want to write Val and Z in another file but I only get the last value of each in the file because fopen(fid,'w+') keeps updating inside the loop. Using a+ plus doesn't help and it keeps appending and never updates after the program is done running.
RIght now I am using a+ then I manually delete the content of that file after i'm done running..writing outside the loop gives me error.
Is there a way I can clear the file after each run?
I think if you open just once with w+, you can write multiple times. The first time will be the beginning of the file and after that data will be appended.
Put opening and closing outside the loop. Before the loop you put
fid=fopen('myfile2.txt','w+')
Fid2=fopen('myfile3.txt','w+')
And you can put closing after the loop
fclose(fid)
fclose(Fid2)
If this really really does not work, then I suggest opening the file once before the loop with w' which will empty the contents. Then you can use a+ inside the loop to append data. You will have a clean file each time.

Prolog how to save file in an existing file

How do I save on an existing file after adding new data
add_a_link(X,Y) :-
tell('alink.txt'),
write(X),
write('.'),
write(Y),
write('.'),
put(10),
told,
write('data written'),
nl.
this code only re-write the text file.
Use open/3 and stream oriented I/O:
open(file, append, S), write(S, info(X,Y)), put_char(S,.), nl(S), close(S).
Using tell/1 and told is extremely unreliable. It easily happens that the output is written to another file accidentally.
Edit: Here is an example to illustrate the extremely unreliable properties of tell/1 and told.
Say, you write tell(file), X > 3, write(biggervalue), told. This works fine as long as X > 3. But with a smaller value this query fails and nothing is written. That might have been your intention. However, the next output somewhere else in your program will now go into the file. That's something you never want to happen. For this reason ISO-Prolog does not have tell/1 and told but rather open/3 and close/1.

problem writing in file

FILE *ExcelFile = fopen("testdata.csv","w");
if (ExcelFile == NULL)
return -1;
fprintf(ExcelFile,"1 2 3");
fprintf(ExcelFile,"\n");
fclose(ExcelFile);
//==============================================
FILE *fa = fopen("testdata.csv","w");
if (fa == NULL)
return -1;
fseek (fa, 6 , SEEK_SET );
fprintf(ExcelFile,"a");
fclose(fa);
in the code i have write 1 2 3 in the file and also inserted '\n' (required for the program) now i want to place a after 3 like 1 2 3 a but hte problem iam facing is that my code erase all char an simply write a . help required .thanks
First of all, a CSV file should have "comma separated values", as the name indicates. So, rather than "1 2 3", you'd better have "1,2,3" or "1;2;3".
Now, there are multiple ways of opening a file : you're only using the "w" as "writing" mode. When you're in writing mode, you're erasing your file. You could use the "a" as "add" mode, which mean that everything will be put after it.
You could also :
1°) First read your file with a "r" mode and store it in memory. Then, close it.
2°) Then, open your file with a "w" mode, copy what you stored, and then make your addendum. Then, close it.
(There is a "reading and writing mode" too, check the link provided by another answer ; but this solution can easily be broken in small pieces, to have small functions doing each their part of the job).
Every time you open your file, you are opening it as a 'w' option. In C, this has a specific meaning : start writing at the beginning of the file.
For your first write of the file, this is okay, but for every subsequent write, you're overwriting your previous content.
Solution Use the 'a' attribute instead here. Like this:
FILE *fa = fopen("testdata.csv","a");
See more information about fopen here...
EDIT
Reading your comments, I understand that when you write again, the next thing starts on a new line. This is because of your initial write 1 2 3 \n (The \n makes a new line).
To correct this you can :
Don't write a '\n' at all.
OR
Read the entire file first, rewrite it without the \n and then write your new a and \n
You want mode "r+". Using mode "a", all writes will go to the end of the file.
You specified w for fopen(), which means "create the file or open for overwrite if already exists".
Therefore, your second call to fopen() cleared the file's contents.
Use a, for: "create the file, or append to it if already exists".
fopen (filename,"a")
a = append

Inserting data to file in c

I need to add a string before the 45th byte in an existing file. I tried using fseek as shown below.
int main()
{
FILE *fp;
char str[] = "test";
fp = fopen(FILEPATH,"a");
fseek(fp,-45, SEEK_END);
fprintf(fp,"%s",str);
fclose(fp);
return(0);
}
I expected that this code will add "test" before the 45th char from EOF, instead, it just appends "test" to the EOF.
Please help me to find the solution.
This is continuation of my previous question
Append item to a file before last line in c
Open it with mode r+ (if it already exists) or a+ (if it doesn't exist and you want to create it). Since you're seeking to 45 bytes before the end of file, I'm assuming it already exists.
fp = fopen(FILEPATH,"r+");
The rest of your code is fine. Also note that this will not insert the text, but will overwrite whatever is currently at that position in the file.
ie, if your file looks like this:
xxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
Then after running this code, it will look like this:
xxxxxxxtestxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
If you really want to insert and not overwrite, then you need to read all the text from SEEK_END-45 to EOF into memory, write test and then write the text back
Don't open it as append (a) if you plan to write at arbitrary positions; it will force all writes to the end of the file. You can use r+ to read or write anywhere.
To avoid platform-specific configurations, always explicitely indicate the binary or text mode in your fopen() call.
This will save you hours of desperations if you port your code one day.

Resources