This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
bbaayyeerr's profile picture

Preference File (Save and Read)

Started by bbaayyeerr, 02 July 2014 - 06:12 PM
bbaayyeerr #1
Posted 02 July 2014 - 08:12 PM
Hello!
I'm trying to make a basic load up scrip where the computer checks where the modem are placed as well as the Password-Server ID, and then after that write it to a file. So far i haven't got any problems making the so called "Preference File" and writing the different values to it, but the problem is that i can't find a way to read the values from the file correctly.

Here is the part working excellent:

function CreateFiles()
if fs.exists("info") then
  print("FILE: INFO EXISTS")
end

for i=1, #rs.getSides() do
  if peripheral.getType(rs.getSides()[i]) == "modem" then
	print("---------------------------------------------------")
	print("Modem found on "..rs.getSides()[i].." side!")
	print("---------------------------------------------------")
	side = rs.getSides()[i]
	sleep(1)
  end
end

if side == 0 then
print("No modem attached! Please place modem on any side!")
sleep(1)
print("Recheck in 10 sek!")
print("---------------------------------------------------")
sleep(10)
os.reboot()
else
print("Writing Modem-side to file...")
sleep(1)
print("---------------------------------------------------")
end
rednet.open(side)
rednet.broadcast("Server?")
local senderId, message, distance = rednet.receive(1)

print("[FROM COMPUTER, ID: "..os.getComputerID().."]: Server?")
sleep(1)

-- This part bellow is just to define the server response! --
local senderId = 23
local message = "Server Here"

-- Regular code once again --
if message == "Server Here" then
ServerID = senderId
else
sleep(1)
print("---------------------------------------------------")
print("No response from Password Server!")
sleep(2)
print("Reboot in 5")
print("---------------------------------------------------")
sleep(5)
os.reboot()
end
print("[FROM SERVER, ID: "..senderId.."]: "..message.."...")
sleep(1)
print("---------------------------------------------------")
print("Writing Server ID to file...")
print("---------------------------------------------------")
sleep(2.5)

	f = fs.open("info", "w")
	f.write("ModemSide="..side.."\nServerID="..ServerID)
	f.close()

print("Main program may now start!")
print("---------------------------------------------------")
sleep(2)
end --[[ END CREATEFILES ]]--

As you can see the graphical look of the script is so far very basic, but it was just to see how the computer responded to the code. ( Don't judge! ;)/>/> )
Now to the part I can't get to work:


function ReadFiles()
local file = io.open("info")
if fs.exists("info") == false then
  print("Pref file not found! ")
  print("ERROR: 372")
end
  ServerID = string.gsub(file:read(), "ServerID=")
  print(ServerID)
  ServerID = tonumber(ServerID)
  if ServerID == 0 then
	print("ServerID not valid!")
  end
  ModemSide = string.gsub(file:read(), "ModemSide=")
  print(ModemSide)
end

Now if you look on the two print parts (They are just there in purpose of debugging), print(ServerID) will print: ServerID="id" and print(ModemSide) will print: ModemSide="side" ("id" & "side" are of curse depending on the defined values of the computer) Why wont it just print "id" & "side"?? The question is how can I make a function that can read the ServerID and ModemSide from the preference file so that I just get "id" & "side" as a variable?
If anyone could help me with this I would be grateful!
//BBAAYYEERR
Edited on 03 July 2014 - 05:08 AM
Lyqyd #2
Posted 02 July 2014 - 09:08 PM
You wouldn't use gsub for this. You'd use string.match. You should also check that the file exists before attempting to open it, and close the handle when you're done with it. And you should specify the mode to open the file in.


local serverID, modemSide
local handle = io.open("info", "r")
if handle then
  serverID = tonumber(string.match(handle:read("*l"), "ServerID=(%d+)"))
  modemSide = string.match(handle:read("*l"), "ModemSide=(%a+)")
  handle:close()
end
bbaayyeerr #3
Posted 02 July 2014 - 09:23 PM
Thank you, for the fast response! :)/>
I've reed on the lua page, about the strange "signs" you use in the code ("*1"), (%d+), (%a+)… But i still don't get what they are used for!? You would possibly not be able to clarify this a bit?? ;)/> Since it seams important to know when dealing with strings!
Thanks! :D/>
Lyqyd #4
Posted 02 July 2014 - 10:05 PM
The io file handles' read method uses a "mode" argument, which is an asterisk followed by a lowercase A or L, for all or line reading. The others are string matching patterns, which are well-documented in the Lua reference manual. Those two patterns are for numeric and alpha-only strings.
bbaayyeerr #5
Posted 02 July 2014 - 10:48 PM
Thanks! :)/>/>/>
So if I get this right, if you are using io.open() instead of the built in API (fs) you have to declare A & L like you have to with .readLine() or .readAll()? In that case it's rather logical!

I tested the provided code from you above, and added two "print" right bellow the "if statement" to see if it would print out modemSide and serverID but then I just got two blank lines when I ran the program!? What am I missing?

Here:

local serverID, modemSide
local handle = io.open("info", "r")
if handle then
  serverID = tonumber(string.match(handle:read("*l"), "ServerID=(%d+)"))
  modemSide = string.match(handle:read("*l"), "ModemSide=(%a+)")
  handle:close()
end
print(serverID)
print(modemSide)

The preference file is looking as it should, so that's not the issue I believe…
Lyqyd #6
Posted 03 July 2014 - 01:00 AM
Can you post the contents of the preference file? If it's misreading it, that will help to narrow down what the problem is.
Bomb Bloke #7
Posted 03 July 2014 - 02:04 AM
For what it's worth, the INI file my Tetris script uses is handled by lines 1142 through to 1183.
bbaayyeerr #8
Posted 03 July 2014 - 06:52 AM
Okey, now let's see!

This part is what creates and write the values to the file:

        f = fs.open("info", "w")
        f.write("ModemSide="..side.."\nServerID="..ServerID)
        f.close()

This is how the preference file looks:

ModemSide=top
ServerID=23
("top" & "23" are just an example, or to be honest this how my current pref-file looks like!)
theoriginalbit #9
Posted 03 July 2014 - 07:36 AM
the problem is because you're reading the file as if it were

ServerID=23
ModemSide=top
however in the file it is

ModemSide=top
ServerID=23
you need to either write them out in the order you're expecting to read them, or read them in the order you write them.
Edited on 03 July 2014 - 05:37 AM
bbaayyeerr #10
Posted 03 July 2014 - 05:01 PM
Okay!
That did actually make it work! Thanks! :D/>
bbaayyeerr #11
Posted 03 July 2014 - 05:53 PM
Now if i like to make a function that reads a certain value from the "pref-file" something like this:

function ReadFile(directory,pref,type)
local handle = io.open(directory, "r")

if handle then
 if type == "number" then
  pref = tonumber(string.match(handle:read("*l"), pref.."=(%d+)"))
 else
  pref = string.match(handle:read("*l"), pref.."=(%a+)")
 end
end

handle:close()
return pref
end

ReadFile("info","ServerID","number")

Now this gives me an blank line once again

So the question is; is it possible make it work like this? So that i don't have to read each line of the pref file only a specific one, declared in the function.
Lyqyd #12
Posted 03 July 2014 - 07:42 PM
For that function to work, you'd have to open the file, read through every line of the file until you found the value you wanted, then close the file handle and return the value. It would definitely be easier to just read through the file once and get the values out that way.
bbaayyeerr #13
Posted 03 July 2014 - 08:30 PM
Sure good point! Thanks everyone for the help provided! :D/>