8bitslime
8bitslime

Reputation: 164

if statement not working in Lua for io.read

I'm trying to make a 'simple' Y/N answer choice thing. (That you saw all the time on old programs) But an If Statement I'm using doesn't seem to want to work. I even print out the variable and it is nowhere near what i want to compare yet it still passes it.

        --Porgram Functions

        function check()

        --Local Variables
            local num = 0
            local loop = true
            io.write("Continue? (Y/N):")
            --User input
            local input = io.read()

            while(loop==true) do

                if (input=="y" or "Y") then

                    print("Ok!")
                    loop = true
                    num = 1

                elseif (input=="n" or "N") then

                    print("Fine...")
                    num = 2

                else

                    print("Invalid Answser!")
                    loop = true
                    num = 0

                end
            end
            print(input)
            return(num)
        end

        print (check())

Upvotes: 2

Views: 1888

Answers (2)

HennyH
HennyH

Reputation: 7944

I would've written your function like this:

function check()
    io.write("Continue? (Y/N): ")
    answer = io.read()
    while( not (answer == "Y" or answer == "N") ) do
        io.write("Invalid Answer! Try again (Y/N): ")
        answer = io.read()
    end
    if answer == "Y" then
        print("Ok!")
        return 1
    else
        print("Fine...")
        return 2
    end
end

print(check())

Some examples of its use:

Continue? (Y/N): Huh?
Invalid Answer! Try again (Y/N): N
Fine...
2
>Exit code: 0
>lua -e "io.stdout:setvbuf 'no'" "a.lua" 
Continue? (Y/N): Huh?
Invalid Answer! Try again (Y/N): Y
Ok!
1

A working version of your code would be:

function check()
    local num = 0
    local loop = true    
    io.write("Continue? (Y/N):")

    while(loop==true) do    
        --User input
        local input = io.read()   
        if (input == "y" or  input == "Y") then    
            print("Ok!")
            num = 1
            loop = false --we want to stop looping if input is valid      
        elseif (input == "n" or input == "N") then    
            print("Fine...")
            num = 2
            loop = false --we want to stop looping if input is valid   
        else
            print("Invalid Answser!")
            -- loop = true no need to set looping to true again
            num = 0    
        end
    end
    return(num)
end

The changes made were:

  1. Get the user input inside the while loop, this way if the input is invalid and the loop goes again the same logic behind getting the input is used, we don't have to code two cases for getting input; one outside the loop the other within. It also pauses execution when the loop starts again, this was what was producing all that output!
  2. input == "y" or "Y" doesn't do what you think. Instead it evaluates to (input == "y") or ("Y"), what you want it input == "y" or input == "Y".
  3. You needed to set loop to false when the input was either "y" or "Y" or "n" or "N", otherwise the loop would continue.
  4. Fourthly setting the loop to true inside the loop is unnecessary, it begins as true, and the only change you can make is to set it to false. And since each of the conditions are mutually exclusive i.e input being "y" or "Y" mutually exclusive to input being "n" or "N" or it being neither "y" or "Y" or "n" or "N". You don't need to worry about it being set to false unless you wanted the loop to end.

Upvotes: 3

Egor Skriptunoff
Egor Skriptunoff

Reputation: 23737

local function check()
   io.write"Continue? (Y/N): "
   local ans, num = {y = 1, n = 2}
   repeat
      num = ans[io.read():lower()] or 3
      io.write(({"Ok!\n","Fine...\n","Invalid Answer! Try again (Y/N): "})[num])
   until num < 3
   return num
end

print (check())

Upvotes: 1

Related Questions