I get an error saying my 'for' limit isn't a number even though I am not referring to that variable

Viewed 38

Basically I'm making a program (for school) where a user inputs a couple of volumes of balls, with a formula you need to get the diameter and then look if the diameter is too big. But one of my variables is supposed to be the name of a ball so I can refer to that in my output (e.g.: you give me a PingPong ball with a maximum diameter of let's say 2 cm. You then give me the amount of balls to run trough the program, 3. Then you give 3 volumes, 1.5, 2.5 and 2 -- output 1.5 - pingpong, 2.5 - not a pingpong, 2 - pingpong) But whenever I run my program and I give the name of my ball I get an error saying that my 'for' limit isn't a number even though I am not referring to that variable but to another one.

local n = io.read("*n")  -- amount of balls 
for getal1 = 1, n do
  local naam_Bal = io.read() -- here I get an error if I enter a string
  local av = io.read("*n")  -- amount of volumes for the type of ball
  local gewenste_Diameter = io.read("*n")  -- maximum diameter
  local volume
  local diameter
  for getal2 = 1, av do
    volume = io.read("*n")   -- volume for each ball
    diameter = 2 * (((3/4)*(volume/math.pi)) ^ (1/3))  -- formula to calculate the diameter
    print(diameter)
  end 
end

It's probably a stupid mistake but I'm really stuck

2 Answers

This is because io.read("*n") leaves EOL (after the number) unread.

What actually happens in your script:

  • local n = io.read("*n") reads number but not EOL.
  • local naam_Bal = io.read() reads EOL of the previous number but not the name.
  • local av = io.read("*n") reads the name.

Solution:
If you have each number on a separate line of input,
you should always use io.read("*n", "*l") instead of io.read("*n").

io.read('*n') seems to behave weirdly. it requires me to press enter twice (both in 5.1.5 and 5.4.2) That behaviour explains why you get an error when entering a string. The previous read of a number had not completed yet.

I suggest not using it and instead use a function like this to input a number to sidestep the issue.

function input_number()
    var line = io.read()
    var num = tonumber(line)
    if not num then
        error("not a number")
    end
end

You may want to improve the rudimentary error handling though.

Related