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

Read() Only Letters

Started by Micheal Pearce, 22 July 2013 - 07:45 PM
Micheal Pearce #1
Posted 22 July 2013 - 09:45 PM
Hello i am trying to do a password system or something alone those lines and i want it to be-able to only take in letters like abc and not numbers like 123 and i know theres a way to do it with os.pullEvent() and that stuff but i was wonder if there was a easier quicker way because i need to convert these characters to binary code so it will be more safe and have numbers in the mix makes it harder to convert to binary Thanks for reading and thanks for help if you do
Engineer #2
Posted 22 July 2013 - 09:57 PM
It is very easy to do. Just make a banned characters table and check if the user types those. To ban numbers, you can check if you can tonumber it. This will not work entirely as read, but mostly it does work.

local x, y =term.getCursorPos()
local s = ""

term.setCursorBlink( true )

while true do
   local e = os.pullEvent()
   if e[1] == "char" and not tonumber( e[2] ) then
       s = s .. e[2]
   elseif e[1] == "key" then
       if e[2] == keys.backspace then
           s = s:sub( 1, s:len() - 1 )
       elseif e[2] == keys.enter then
           break
       end
   end
   term.setCursorPos( x, y )
   term.clearLine()
   term.write( s )
end

term.setCursorBlink( false )
Micheal Pearce #3
Posted 22 July 2013 - 10:12 PM
It is very easy to do. Just make a banned characters table and check if the user types those. To ban numbers, you can check if you can tonumber it. This will not work entirely as read, but mostly it does work.

local x, y =term.getCursorPos()
local s = ""

term.setCursorBlink( true )

while true do
   local e = os.pullEvent()
   if e[1] == "char" and not tonumber( e[2] ) then
	   s = s .. e[2]
   elseif e[1] == "key" then
	   if e[2] == keys.backspace then
		   s = s:sub( 1, s:len() - 1 )
	   elseif e[2] == keys.enter then
		   break
	   end
   end
   term.setCursorPos( x, y )
   term.clearLine()
   term.write( s )
end

term.setCursorBlink( false )

Thanks man
Grim Reaper #4
Posted 23 July 2013 - 12:46 AM
That might not work because you're not capturing the entirity of os.pullEvent as a table, but rather just capturing the first parameter returned: the event. I'm pretty sure that is just a typo on Engineer's behalf, though ;)/>

You could also make a shorter, but perhaps more costly solution, using coroutines:


local _string     = ""
local readRoutine = coroutine.create (function()
                                        _string = read()
                                      end)

-- Initialize the coroutine.
coroutine.resume (readRoutine)

-- Resume the coroutine with events as long as the coroutine is alive.
while coroutine.status (readRoutine) ~= "dead" do
    local event, character = os.pullEvent()

    if not tonumber (character) then
        coroutine.resume (readRoutine, character)
    end
end

print (_string)