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

[lua][error] Numbers and strings

Started by timberwolf, 10 December 2012 - 05:08 AM
timberwolf #1
Posted 10 December 2012 - 06:08 AM
I am trying to make a remote printing program, kinda like a wifi printer. I am having trouble with the string to number conversion/comparison. I know I have multiple errors; some in the client, some in the server, but the most prominent is on line 30 which produces:

print:30: attempt to compare string with number expected, got string


term.clear()
term.setCursorPos(1,1)
local printing = true
local page = true
repeat
  rednet.send(49,"newPage")
  local id,msg = rednet.receive(5)
  if msg == "true" then
	page = true
  elseif msg == "false" then
	page = false
  else
	print(msg)
	print(" ")
	page = false
  end
  if page == false then
	printing = false
  end
  local line = 1
  rednet.send(49,"getSize")
  local id,w = rednet.receive(5)
  local id,h = rednet.receive(5)
  repeat
	local l = read()
	if l == "exit" then
	  rednet.send(49,"finish")
	  printing = false
	  line = h
	elseif string.len(l) <= w then
	  rednet.send(49,l)
	  line = line + 1
	  rednet.send(49,"setLine," .. line)
	else
	  print("Line is too long. Max is: " .. w)
	end
  until line == h
  rednet.send(49,"endPage")
until printing == false
if page == false then
  print("Out Of Paper.")
end
Cranium #2
Posted 10 December 2012 - 07:15 AM

local id,w = rednet.receive(5)
local id,h = rednet.receive(5)
--should be
local id,tonumber(w) = rednet.receive(5)
local id,tonumber(h) = rednet.receive(5)
The second variable returned by rednet.receive() is a string, so if you are sending numbers, you need to convert them to numbers before you can compare them. You can't compare numbers to strings.
snoble2022 #3
Posted 10 December 2012 - 09:47 AM
I agree with cranium.
If you're sending numbers of rednet put them both as strings because it compares faster
timberwolf #4
Posted 10 December 2012 - 03:06 PM

local id,w = rednet.receive(5)
local id,h = rednet.receive(5)
--should be
local id,tonumber(w) = rednet.receive(5)
local id,tonumber(h) = rednet.receive(5)
The second variable returned by rednet.receive() is a string, so if you are sending numbers, you need to convert them to numbers before you can compare them. You can't compare numbers to strings.

That gave me the error:

bios:338: [string "print"]:22: syntax error

so I tried:


local id,w = rednet.receive(5)
local id,h = rednet.receive(5)
w = tonumber(w)
h = tonumber(h)

and got:

print:32: attempt to compare nil with number
faubiguy #5
Posted 11 December 2012 - 04:02 AM
If w or h cannot be turned into a number, tonumber is returning nil instead, so it tries to compare nil to string.len(l). What do the messages look like that its receiving?
timberwolf #6
Posted 11 December 2012 - 05:48 AM
OK, so the server is what my problem is…
Here is the server code:

rednet.open("front")
local printer = peripheral.wrap("left")
local curID = ""
function parse(command,id)
  if command == "newPage" then
	local page = printer.newPage()
	rednet.send(id,page)
  elseif command == "getSize" then
	local w,h = printer.getPageSize()
	rednet.send(id,w)
	rednet.send(id,h)
  elseif command == "finish" then
	printer.endPage()
	curID = ""
  elseif command == "endPage" then
	printer.endPage()
  elseif string.find(command, "setLine,") ~= nil then
	local line = string.sub(command,string.find(command,",") + 1)
	printer.setCursorPos(1,line)
  else
	rednet.send(id,"Invalid Command")
  end
end
while true do
  local id,msg = rednet.receive()
  if curID ~= "" and id == curID then
	parse(msg,id)
  elseif curID == "" then
	curID = id
	parse(msg)
  elseif id ~= curID then
	rednet.send(id,"Printer In Use.")
  end
end
timberwolf #7
Posted 12 December 2012 - 04:41 AM
I managed to get it working myself.

Client:

shell.run("clear")
term.setTextColor(colors.red)
local printing = true
local page = true
repeat
  rednet.send(49,"newPage")
  local id,msg = rednet.receive(1)
  if msg == "true" then
    page = true
  elseif msg == "false" then
    page = false
  else
    print(msg)
    print(" ")
    printing = false
  end
  if page == false then
    printing = false
  end
  local line = 1
  rednet.send(49,"getSize")
  local id,w = rednet.receive(1)
  local id,h = rednet.receive(1)
  w = tonumber(w)
  h = tonumber(h)
  print(" ")
  repeat
    local l = read()
    if l == "exit" then
	  rednet.send(49,"finish")
	  printing = false
	  line = h
    elseif string.len(l) < w then
	  rednet.send(49,l)
	  line = line + 1
	  rednet.send(49,"setLine," .. line)
    else
	  print("Line is too long. Max is: " .. w)
    end
  until line == h
  if printing then
    rednet.send(49,"endPage")
  end
until printing == false
if page == false then
  print("Out of Paper.")
end

Server:

rednet.open("front")
local printer = peripheral.wrap("left")
local curID = ""
function parse(command,id)
  if command == "newPage" then
    local page = printer.newPage()
    rednet.send(id,tostring(page))
  elseif command == "getSize" then
    local w,h = printer.getPageSize()
    rednet.send(id,tostring(w))
    rednet.send(id,tostring(h))
  elseif command == "finish" then
    printer.endPage()
    curID = ""
  elseif command == "endPage" then
    printer.endPage()
  elseif string.find(command, "setLine,") ~= nil then
    local line = tonumber(string.sub(command,string.find(command,",") + 1))
    printer.setCursorPos(1,line)
  else
    printer.write(command)
  end
end
while true do
  local id,msg = rednet.receive()
  if curID ~= "" and id == curID then
    parse(msg,id)
  elseif curID == "" then
    curID = id
    parse(msg,id)
  elseif id ~= curID then
    rednet.send(id,"Printer In Use.")
  end
end