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

How do I input something into my computer, then save it to a different file, then see if there is something on that line.

Started by n1ghtk1ng, 13 September 2012 - 12:02 AM
n1ghtk1ng #1
Posted 13 September 2012 - 02:02 AM
I have been wanting to make a todo-list of some kind, so that whenever I input something, checks if there's something on ? line, if so, write on that line, if not, write on the next line, and so on.
EDIT: I would REALLY enjoy it if someone cleaned up my code. I know there are doing this better, (I tried to do it with a table, but I couldn't figure how to input a string into one, only a value) Any additions/tweaks would be great.
EDIT2:I just turned 13 and I've only programmed for ~2 1/2 weeks, this being my first programming language, so it would really help me :)/>/>


--CONFIG--
local disSide = "top"
local filer = fs.open("list", "r")
local filew = fs.open("list", "w")
v = 1

--FUNCTIONS--
function saveList()
filew.writeLine(todo1)
filew.writeLine(todo2)
filew.writeLine(todo3)
filew.writeLine(todo4)
filew.writeLine(todo5)
filew.close()
end
function loadList()
lTodo1 = filer.readLine()
lTodo2 = filer.readLine()
lTodo3 = filer.readLine()
lTodo4 = filer.readLine()
lTodo5 = filer.readLine()
filer.close()
end
--CODE--
shell.run("clear")
loadList()
print("Todo List v0.2")
print("What would you like to do?")
input = read()
if input == "new" then
if lTodo1 == nil then
  print("What would you like to write?")
  local input = read()
  input = todo1
  saveList()
elseif lTodo1 ~= nil then
  v = v + 1
  if v == 2 then
   if lTodo2 == nil then
	print("What would you like to write?")
	local input = read()
	input = todo2
	saveList()
   elseif lTodo2 ~= nil then
	v = v + 1
   if v == 3 then
	if lTodo3 == nil then
	 print("What would you like to write?")
	 local input = read()
	 input = todo3
	 saveList()
	elseif lTodo3 ~= nil then
	 v = v + 1
	  if v == 4 then
	   if lTodo4 == nil then
		print("What would you like to write?")
		local input = read()
		input = todo4
		saveList()
	   elseif lTodo4 ~= nil then
	   v = v + 1
	   if v == 5 then
		if lTodo5 == nil then
		 print("What would you like to write?")
		 local input = read()
		 input = todo5
		 saveList()
		elseif lTodo5 ~= nil then
		 v = v + 1
		end
	   end
	  end
	 end
	end
   end
  end
end
end
end
Bubba #2
Posted 13 September 2012 - 02:31 AM
Now if I'm reading what you said correctly, you are requesting a way to write lines to a file and then read them back on request. If this is what you want, then your method is a very messy and inefficient way to go about it. Tables are indeed what you would want to use for something like this.

Inputting strings into tables is fairly simple. Just use the 'table.insert(tableName, string)' function.
Here is an example:

strTable = {} -- initialize your table
function readFile()
   fileOpen = fs.open("list", "r")
   tempString = fileOpen.readLine()
   while tempString ~= nil do --While the tempString variable is not empty
	  table.insert(strTable, tempString) --Insert tempString into strTable
	  tempString = fileOpen.readLine()
   end
   fileOpen.close()
end
readFile()
Your table will now contain the lines from that file. To read those lines, you can do something like this:

function readTable()
   for i,v in ipairs(strTable) do
	 print(i..": "..v)
	 os.pullEvent() --Pauses the program in case your file has too many lines for the computer to handle
end
end
readTable()

In case you haven't come across for loops and ipairs, here is a link to the lua PIL.

Incorporate tables and for loops into your code and it will be much more useable and much, much simpler to use.

Good luck!
n1ghtk1ng #3
Posted 13 September 2012 - 02:54 AM
Now if I'm reading what you said correctly, you are requesting a way to write lines to a file and then read them back on request. If this is what you want, then your method is a very messy and inefficient way to go about it. Tables are indeed what you would want to use for something like this.

Inputting strings into tables is fairly simple. Just use the 'table.insert(tableName, string)' function.
Here is an example:

strTable = {} -- initialize your table
function readFile()
   fileOpen = fs.open("list", "r")
   tempString = fileOpen.readLine()
   while tempString ~= nil do --While the tempString variable is not empty
	  table.insert(strTable, tempString) --Insert tempString into strTable
	  tempString = fileOpen.readLine()
   end
   fileOpen.close()
end
readFile()
Your table will now contain the lines from that file. To read those lines, you can do something like this:

function readTable()
   for i,v in ipairs(strTable) do
	 print(i..": "..v)
	 os.pullEvent() --Pauses the program in case your file has too many lines for the computer to handle
end
readTable()

In case you haven't come across for loops and ipairs, here is a link to the lua PIL.

Incorporate tables and for loops into your code and it will be much more useable and much, much simpler to use.

Good luck!

Quick Question, would tempString be where I input a string/todo?
Bubba #4
Posted 13 September 2012 - 03:14 AM
Quick Question, would tempString be where I input a string/todo?

Nope. tempString is where each line from the file is read to and stored temporarily so it can be inserted into the table. To input things to your file, you can use this function:

function writeToFile()
   fileOpen = fs.open("list", "w")
   while true do
	 term.write("Input task: ")
	 input = io.read()
	 if input == nil then
		fileOpen.close()
		break
	 else
		fileOpen.writeLine(input)
	 end
   end
end
n1ghtk1ng #5
Posted 13 September 2012 - 10:27 PM
Quick Question, would tempString be where I input a string/todo?

Nope. tempString is where each line from the file is read to and stored temporarily so it can be inserted into the table. To input things to your file, you can use this function:

function writeToFile()
   fileOpen = fs.open("list", "w")
   while true do
	 term.write("Input task: ")
	 input = io.read()
	 if input == nil then
		fileOpen.close()
		break
	 else
		fileOpen.writeLine(input)
	 end
   end
end

I'm about to finish the code, but another quick question, everytime I enter a new todo, it asks for another Input, how can I just enter one input, then if I want to input another todo, it won't erase the previous one, but write it on the Next Line?(Unless it does that and I'm just using it wrong)
Here's the code, what did I do wrong?

--CONFIG--
strTable = {}
--FUNCTIONS--
function readFile()
file = fs.open("list", "r")
tempString = file.readLine()
while tempString ~= nil do
  table.insert(strTable, tempString)
  tempString = file.readLine()
end
file.close()
end
function readTable()
for i, v in ipairs(strTable) do
  print(i..": "..v)
  os.pullEvent()
end
end
function writeToFile()
local file = fs.open("list", "w")
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == nil then
   file.close()
   break
  else
   file.writeLine(input)
  end
end
end
--CODE--
shell.run("clear")
print("Todo List v1.1 Loaded")
print("What would you like to do?")
local input = read()
if input == "newtodo" then
print("What would you like to write?")
writeToFile()
elseif input == "display" then
readFile()
readTable()
end
Bubba #6
Posted 14 September 2012 - 01:29 AM
Ah. I apologize, I wrote my function with a minor error. Right now what the writeToFile() function does is open the file in write mode each time you call the function, meaning that the file is wiped clean every time.
This should work:

function writeToFile()
local file = fs.open("list", "a") --open it in append mode each time
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == nil then
   file.close()
   break
  elseif input == "/erase" then --You can remove this if you want but you might want a way to remove the contents of the file
	 file.close()
	 file = fs.open("list","w")
	 file.close()
  else
   file.writeLine(input)
  end
end
end
n1ghtk1ng #7
Posted 14 September 2012 - 02:33 AM
Ah. I apologize, I wrote my function with a minor error. Right now what the writeToFile() function does is open the file in write mode each time you call the function, meaning that the file is wiped clean every time.
This should work:

function writeToFile()
local file = fs.open("list", "a") --open it in append mode each time
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == nil then
   file.close()
   break
  elseif input == "/erase" then --You can remove this if you want but you might want a way to remove the contents of the file
	 file.close()
	 file = fs.open("list","w")
	 file.close()
  else
   file.writeLine(input)
  end
end
end
I've been troubling shooting, but I guess the FS API just isn't my thing. Everytime I input something, I go into the file that it writes to (list) and it doesn't get change, but when I enter /erase, it says it does (in Notepad++), it says "This file has been modified by another program…." When I used to input something, it said that, and it wrote it, but now (in the new function writeToFile) it doesn't write anything. How can I fix it?
EDIT: I really want to thank you on how much you've helped me, since I'm teaching myself, I have no-one to do what you're doing. Thanks alot, what you're doing really means alot to me.
EDIT2: I added a break after the, so I think that part worked (it only asks for an input once)

  else
   file.writeLine(input)


This is what I have so far :

--CONFIG--
strTable = {}
v = 0
--FUNCTIONS--
function readFile()
file = fs.open("list", "r")
tempString = file.readLine()
while tempString ~= nil do
  table.insert(strTable, tempString)
  tempString = file.readLine()
end
file.close()
end
function readTable()
for i, v in ipairs(strTable) do
  print(i..": "..v)
  os.pullEvent()
end
end
function writeToFile()
local file = fs.open("list", "a")
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == nil then
   file.close()
   break
  elseif input == "/erase" then
		 file.close()
		 file = fs.open("list","w")
		 file.close()
  else
   file.writeLine(input)
  end
end
end
--CODE--
shell.run("clear")
print("Todo List v1.1 Loaded")
print("What would you like to do?")
local input = read()
if input == "newtodo" then
  print("What would you like to write?")
  writeToFile()
  print("Would you like to enter another Todo?")
  input = read()
  if input == "yes" then
   print("What would you like to write?")
   writeToFile()
  elseif input == "no" then
   shell.run("clear")
  end
elseif input == "display" then
readFile()
readTable()
end
Bubba #8
Posted 14 September 2012 - 03:14 AM
I really want to thank you on how much you've helped me, since I'm teaching myself, I have no-one to do what you're doing. Thanks alot, what you're doing really means alot to me.
No problem. Thank you for being patient with my mistakes :)/>/>

Okay so there are a couple of problems. First off is the file name we are saving to. Saving as "list" removes the functionality of the 'ls' command (used to list all the files in the current folder), so I renamed it 'aList'. Another problem is that when the user hits enter instead of inputting a task, the returned result is not nil but an empty string value (confusing I know). Anyway, here is the fixed code: tested and all this time :P/>/>

--CONFIG--
strTable = {}
v = 0
--FUNCTIONS--
function readFile()
file = fs.open("aList", "r")
tempString = file.readLine()
while tempString ~= nil do
  table.insert(strTable, tempString)
  tempString = file.readLine()
end
file.close()
end
function readTable()
for i, v in ipairs(strTable) do
  print(i..": "..v)
  os.pullEvent()
end
end
function writeToFile()
local file = fs.open("aList", "a")
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == "" then
   file.close()
   break
  elseif input == "/erase" then
   file.close()
   file = fs.open("list","w")
   file.close()
  else
   file.writeLine(input)
  end
end
end
--CODE--
shell.run("clear")
print("Todo List v1.1 Loaded")
print("What would you like to do?")
local input = read()
if input == "newtodo" then
  print("What would you like to write?")
  writeToFile()
  print("Would you like to enter another Todo?")
  input = read()
  if input == "yes" then
   print("What would you like to write?")
   writeToFile()
  elseif input == "no" then
   shell.run("clear")
  end
elseif input == "display" then
readFile()
readTable()
end
n1ghtk1ng #9
Posted 14 September 2012 - 09:26 PM
I really want to thank you on how much you've helped me, since I'm teaching myself, I have no-one to do what you're doing. Thanks alot, what you're doing really means alot to me.
No problem. Thank you for being patient with my mistakes :)/>/>

Okay so there are a couple of problems. First off is the file name we are saving to. Saving as "list" removes the functionality of the 'ls' command (used to list all the files in the current folder), so I renamed it 'aList'. Another problem is that when the user hits enter instead of inputting a task, the returned result is not nil but an empty string value (confusing I know). Anyway, here is the fixed code: tested and all this time :P/>/>

--CONFIG--
strTable = {}
v = 0
--FUNCTIONS--
function readFile()
file = fs.open("aList", "r")
tempString = file.readLine()
while tempString ~= nil do
  table.insert(strTable, tempString)
  tempString = file.readLine()
end
file.close()
end
function readTable()
for i, v in ipairs(strTable) do
  print(i..": "..v)
  os.pullEvent()
end
end
function writeToFile()
local file = fs.open("aList", "a")
while true do
  term.write("Input Task: ")
  input = io.read()
  if input == "" then
   file.close()
   break
  elseif input == "/erase" then
   file.close()
   file = fs.open("list","w")
   file.close()
  else
   file.writeLine(input)
  end
end
end
--CODE--
shell.run("clear")
print("Todo List v1.1 Loaded")
print("What would you like to do?")
local input = read()
if input == "newtodo" then
  print("What would you like to write?")
  writeToFile()
  print("Would you like to enter another Todo?")
  input = read()
  if input == "yes" then
   print("What would you like to write?")
   writeToFile()
  elseif input == "no" then
   shell.run("clear")
  end
elseif input == "display" then
readFile()
readTable()
end

This was excellent, exactly what I was trying to accomplish, except that when I enter another todo, instead of adding the todo to the list, it just erases the previous one. Any suggestions on how I could do that?

EDIT: Never mind! It works exactly how I wanted, Thanks so much for your help! I really appreciate it!
EDIT2: (Last question until I stop bugging you) How can I display the function on the monitor on my top side?

shell.run("monitor", "top", "readFile") ;
shell.run("monitor", "top", "readTable")
I tried this but it doesn't work.
icehaunter #10
Posted 15 September 2012 - 01:01 AM
shel.run actually initializes a PROGRAM, not a function. To access monitors from the actual program, you need this:

mon = peripheral.wrap("top") -- this is to bind the monitor.
mon.setCursorPos(1, 1) -- this will set the cursor position to the start. Basically, now mon has all functions as term. Like term.write() or term.clear() 
mon.write("any random string") -- this one will actually write on the monitor. Since term.write()  does not understand n, we need to use this:
mon.setCursorPos(1,2) -- this will set cursor on the second line so
mon.write("yo")  -- this will be on the second line.

To learn more about it visit http://www.computercraft.info/wiki/index.php?title=Peripheral_(API)
Good luck
Bubba #11
Posted 15 September 2012 - 02:01 AM
shell.run("monitor", "top", "readFile") ;
shell.run("monitor", "top", "readTable")

I tried this but it doesn't work.

Edit: Ninja'd by icehaunter, but I think that you will still want to try these functions as it is much more user friendly. No offence icehaunter :)/>/>

The reason that doesn't work is because you are trying to run functions rather than a program. I would actually suggest not using the default monitor program. The difficulty with using it is that it only prints to the monitor, making it difficult to input commands. Instead try using the peripheral api.

Here are the codes that I modified to make it print to the monitor and the terminal at the same time:
Config

monitor = peripheral.wrap("top")
monX, monY = monitor.getSize()
termX, termY = term.getSize()
Functions

function write(text,boolValue)
  x,y = monitor.getCursorPos()
  if y == monY then
	monitor.scroll(1) --If the cursor is at the bottom of the console, scroll down
  end
  monitor.write(text) --Write to both the monitor...
  term.write(text) --...and the computer terminal
  if y ~= monY and boolValue ~= false then
	monitor.setCursorPos(1, y + 1) --Goto the next line if the user does not pass false to boolValue
  end
end
function clear()
  term.clear()
  term.setCursorPos(1,1)
  monitor.clear()
  monitor.setCursorPos(1,1)
end
Modified Functions

function writeToFile()
local file = fs.open("aList", "a")
while true do
  write("Input Task: ",false) --Make sure that the monitor does not move to the next line yet
  input = io.read()
  currentX,currentY = monitor.getCursorPos()
  monitor.write(input)
  if currentY ~= monY then
	monitor.setCursorPos(1,currentY + 1) --Now it can move to the next line
  end
  if input == "" then
   file.close()
   break
  elseif input == "/erase" then
	file.close()
	file = fs.open("list","w")
	file.close()
  else
   file.writeLine(input)
  end
end
end
Modification to main code: Replaced any mention of 'shell.run("clear")' with the function clear()

And here's the whole file all together:
Spoiler

--CONFIG--
strTable = {}
v = 0
monitor = peripheral.wrap("top")
monX, monY = monitor.getSize()
termX, termY = term.getSize()
--FUNCTIONS--
function write(text,boolValue)
  x,y = monitor.getCursorPos()
  if y == monY then
	monitor.scroll(1) --If the cursor is at the bottom of the console, scroll down
  end
  monitor.write(text) --Write to both the monitor...
  term.write(text) --...and the computer terminal
  if y ~= monY and boolValue ~= false then
	monitor.setCursorPos(1, y + 1) --Goto the next line if the user does not pass false to boolValue
  end
end
function clear()
  term.clear()
  term.setCursorPos(1,1)
  monitor.clear()
  monitor.setCursorPos(1,1)
end
function readFile()
file = fs.open("aList", "r")
tempString = file.readLine()
while tempString ~= nil do
  table.insert(strTable, tempString)
  tempString = file.readLine()
end
file.close()
end
function readTable()
for i, v in ipairs(strTable) do
  write(i..": "..v)
  currentX, currentY = term.getCursorPos()
  if currentY ~= termY then
	term.setCursorPos(1, currentY + 1)
  end
  os.pullEvent()
end
end
function writeToFile()
local file = fs.open("aList", "a")
while true do
  write("Input Task: ",false) --Make sure that the monitor does not move to the next line yet
  input = io.read()
  currentX,currentY = monitor.getCursorPos()
  monitor.write(input)
  if currentY ~= monY then
	monitor.setCursorPos(1,currentY + 1) --Now it can move to the next line
  end
  if input == "" then
   file.close()
   break
  elseif input == "/erase" then
	file.close()
	file = fs.open("list","w")
	file.close()
  else
   file.writeLine(input)
  end
end
end
--CODE--
clear()
print("Todo List v1.1 Loaded")
print("What would you like to do?")
local input = read()
if input == "newtodo" then
  print("What would you like to write?")
  writeToFile()
  print("Would you like to enter another Todo?")
  input = read()
  if input == "yes" then
   print("What would you like to write?")
   writeToFile()
  elseif input == "no" then
   term.setCursorPos(1,1)
   clear()
  end
elseif input == "display" then
readFile()
readTable()
end
n1ghtk1ng #12
Posted 15 September 2012 - 03:23 AM
shell.run("monitor", "top", "readFile") ; shell.run("monitor", "top", "readTable") I tried this but it doesn't work.
Edit: Ninja'd by icehaunter, but I think that you will still want to try these functions as it is much more user friendly. No offence icehaunter :)/>/> The reason that doesn't work is because you are trying to run functions rather than a program. I would actually suggest not using the default monitor program. The difficulty with using it is that it only prints to the monitor, making it difficult to input commands. Instead try using the peripheral api. Here are the codes that I modified to make it print to the monitor and the terminal at the same time: Config
 monitor = peripheral.wrap("top") monX, monY = monitor.getSize() termX, termY = term.getSize() 
Functions
 function write(text,boolValue) x,y = monitor.getCursorPos() if y == monY then monitor.scroll(1) --If the cursor is at the bottom of the console, scroll down end monitor.write(text) --Write to both the monitor... term.write(text) --...and the computer terminal if y ~= monY and boolValue ~= false then monitor.setCursorPos(1, y + 1) --Goto the next line if the user does not pass false to boolValue end end function clear() term.clear() term.setCursorPos(1,1) monitor.clear() monitor.setCursorPos(1,1) end 
Modified Functions
 function writeToFile() local file = fs.open("aList", "a") while true do write("Input Task: ",false) --Make sure that the monitor does not move to the next line yet input = io.read() currentX,currentY = monitor.getCursorPos() monitor.write(input) if currentY ~= monY then monitor.setCursorPos(1,currentY + 1) --Now it can move to the next line end if input == "" then file.close() break elseif input == "/erase" then file.close() file = fs.open("list","w") file.close() else file.writeLine(input) end end end 
Modification to main code: Replaced any mention of 'shell.run("clear")' with the function clear() And here's the whole file all together:
Spoiler
 --CONFIG-- strTable = {} v = 0 monitor = peripheral.wrap("top") monX, monY = monitor.getSize() termX, termY = term.getSize() --FUNCTIONS-- function write(text,boolValue) x,y = monitor.getCursorPos() if y == monY then monitor.scroll(1) --If the cursor is at the bottom of the console, scroll down end monitor.write(text) --Write to both the monitor... term.write(text) --...and the computer terminal if y ~= monY and boolValue ~= false then monitor.setCursorPos(1, y + 1) --Goto the next line if the user does not pass false to boolValue end end function clear() term.clear() term.setCursorPos(1,1) monitor.clear() monitor.setCursorPos(1,1) end function readFile() file = fs.open("aList", "r") tempString = file.readLine() while tempString ~= nil do table.insert(strTable, tempString) tempString = file.readLine() end file.close() end function readTable() for i, v in ipairs(strTable) do write(i..": "..v) currentX, currentY = term.getCursorPos() if currentY ~= termY then term.setCursorPos(1, currentY + 1) end os.pullEvent() end end function writeToFile() local file = fs.open("aList", "a") while true do write("Input Task: ",false) --Make sure that the monitor does not move to the next line yet input = io.read() currentX,currentY = monitor.getCursorPos() monitor.write(input) if currentY ~= monY then monitor.setCursorPos(1,currentY + 1) --Now it can move to the next line end if input == "" then file.close() break elseif input == "/erase" then file.close() file = fs.open("list","w") file.close() else file.writeLine(input) end end end --CODE-- clear() print("Todo List v1.1 Loaded") print("What would you like to do?") local input = read() if input == "newtodo" then print("What would you like to write?") writeToFile() print("Would you like to enter another Todo?") input = read() if input == "yes" then print("What would you like to write?") writeToFile() elseif input == "no" then term.setCursorPos(1,1) clear() end elseif input == "display" then readFile() readTable() end 

I troubleshooted for a while, but I still couldn't figure it out. It still isn't displaying on the monitor. How can I get it to display?
Bubba #13
Posted 15 September 2012 - 03:31 AM
Hmm. It's working for me. Did you use the entire code from the spoiler or did you add in the functions listed? Because I may have forgotten to list something I modified in the listed ones.
n1ghtk1ng #14
Posted 15 September 2012 - 05:28 AM
Hmm. It's working for me. Did you use the entire code from the spoiler or did you add in the functions listed? Because I may have forgotten to list something I modified in the listed ones.
I added in the functions listed(and modified the one)
EDIT: I copied + pasted what you told me to. I know I've said this like a million times, but THANK YOU SOOOOOOO MUCH :)/>/>. You really helped me :P/>/>
icehaunter #15
Posted 15 September 2012 - 12:29 PM
ChallengeMe, it is ok, I was going for ninjaing, so it was a little short :)/>/>.
(Actually I replied at 3am here, so i was unable to do full listing)
Keep up your full answers) Respect
Bubba #16
Posted 15 September 2012 - 06:40 PM
Hmm. It's working for me. Did you use the entire code from the spoiler or did you add in the functions listed? Because I may have forgotten to list something I modified in the listed ones.
I added in the functions listed(and modified the one)
EDIT: I copied + pasted what you told me to. I know I've said this like a million times, but THANK YOU SOOOOOOO MUCH :)/>/>. You really helped me :P/>/>
You're welcome :D/>/> It is working now right?

ChallengeMe, it is ok, I was going for ninjaing, so it was a little short :)/>/>.
(Actually I replied at 3am here, so i was unable to do full listing)
Keep up your full answers) Respect

Thanks :ph34r:/>/>