How to restrict the length of a word
#1
Posted 30 December 2012 - 04:12 AM
I'm making a login screen where user needs to input username and password and I can't figure out, how to restrict the length that user is allowed to type?
#2
Posted 30 December 2012 - 04:24 AM
here you have original read function
function read( _sReplaceChar, _tHistory )
term.setCursorBlink( true )
local sLine = ""
local nHistoryPos = nil
local nPos = 0
if _sReplaceChar then
_sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
end
local w, h = term.getSize()
local sx, sy = term.getCursorPos()
local function redraw( _sCustomReplaceChar )
local nScroll = 0
if sx + nPos >= w then
nScroll = (sx + nPos) - w
end
term.setCursorPos( sx, sy )
local sReplace = _sCustomReplaceChar or _sReplaceChar
if sReplace then
term.write( string.rep(sReplace, string.len(sLine) - nScroll) )
else
term.write( string.sub( sLine, nScroll + 1 ) )
end
term.setCursorPos( sx + nPos - nScroll, sy )
end
while true do
local sEvent, param = os.pullEvent()
if sEvent == "char" then
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
nPos = nPos + 1
redraw()
elseif sEvent == "key" then
if param == keys.enter then
-- Enter
break
elseif param == keys.left then
-- Left
if nPos > 0 then
nPos = nPos - 1
redraw()
end
elseif param == keys.right then
-- Right
if nPos < string.len(sLine) then
nPos = nPos + 1
redraw()
end
elseif param == keys.up or param == keys.down then
-- Up or down
if _tHistory then
redraw(" ");
if param == keys.up then
-- Up
if nHistoryPos == nil then
if #_tHistory > 0 then
nHistoryPos = #_tHistory
end
elseif nHistoryPos > 1 then
nHistoryPos = nHistoryPos - 1
end
else
-- Down
if nHistoryPos == #_tHistory then
nHistoryPos = nil
elseif nHistoryPos ~= nil then
nHistoryPos = nHistoryPos + 1
end
end
if nHistoryPos then
sLine = _tHistory[nHistoryPos]
nPos = string.len( sLine )
else
sLine = ""
nPos = 0
end
redraw()
end
elseif param == keys.backspace then
-- Backspace
if nPos > 0 then
redraw(" ");
sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
nPos = nPos - 1
redraw()
end
elseif param == keys.home then
-- Home
nPos = 0
redraw()
elseif param == keys.delete then
if nPos < string.len(sLine) then
redraw(" ");
sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
redraw()
end
elseif param == keys["end"] then
-- End
nPos = string.len(sLine)
redraw()
end
end
end
term.setCursorBlink( false )
term.setCursorPos( w + 1, sy )
print()
return sLine
end
#3
Posted 30 December 2012 - 04:26 AM
function readLen(prompt, minLen,maxLen,isPassword)
while true do
write(prompt)
--//read the line; if isPassword is true, pass "*" as the char to display, otherwise nil so it displays what's typed
local sInput=read(isPassword and "*" or nil)
--//if the length is less than min or greater than max...
if #sInput<minLen or #sInput>maxLen then
--//...complain
print("Must be between "..minLen.." and "..maxLen.." characters long!")
else --//not too long or short, return it
return sInput
end
end
end
--//just call it instead of read, passing the prompt, min and max lengths, and optionally "true" if you're reading a password
local username=readLen("Enter username : ",1,16)
--//declare a var for the password before the loop
local password
--//quick loop
while true do
password=readLen("Enter password : ",4,16,true)
--//local declared inside loop, will go away when the loop ends
local pw2=readLen("Confirm password : ",4,16,true)
--//see if they match
if pw2==password then
break --//pws match, end the while loop
end
print("Passwords don't match! Try again")
end
:edit: or, you could modify the original read function grabie posted, if checking after and forcing re-entry bothers you.
#4
Posted 30 December 2012 - 04:38 AM
I have one somewhere on my pc, i'll try find it now, else I'll make a quick one
#5
Posted 30 December 2012 - 04:39 AM
grabie2, on 30 December 2012 - 04:24 AM, said:
here you have original read function
function read( _sReplaceChar, _tHistory )
term.setCursorBlink( true )
local sLine = ""
local nHistoryPos = nil
local nPos = 0
if _sReplaceChar then
_sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
end
local w, h = term.getSize()
local sx, sy = term.getCursorPos()
local function redraw( _sCustomReplaceChar )
local nScroll = 0
if sx + nPos >= w then
nScroll = (sx + nPos) - w
end
term.setCursorPos( sx, sy )
local sReplace = _sCustomReplaceChar or _sReplaceChar
if sReplace then
term.write( string.rep(sReplace, string.len(sLine) - nScroll) )
else
term.write( string.sub( sLine, nScroll + 1 ) )
end
term.setCursorPos( sx + nPos - nScroll, sy )
end
while true do
local sEvent, param = os.pullEvent()
if sEvent == "char" then
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
nPos = nPos + 1
redraw()
elseif sEvent == "key" then
if param == keys.enter then
-- Enter
break
elseif param == keys.left then
-- Left
if nPos > 0 then
nPos = nPos - 1
redraw()
end
elseif param == keys.right then
-- Right
if nPos < string.len(sLine) then
nPos = nPos + 1
redraw()
end
elseif param == keys.up or param == keys.down then
-- Up or down
if _tHistory then
redraw(" ");
if param == keys.up then
-- Up
if nHistoryPos == nil then
if #_tHistory > 0 then
nHistoryPos = #_tHistory
end
elseif nHistoryPos > 1 then
nHistoryPos = nHistoryPos - 1
end
else
-- Down
if nHistoryPos == #_tHistory then
nHistoryPos = nil
elseif nHistoryPos ~= nil then
nHistoryPos = nHistoryPos + 1
end
end
if nHistoryPos then
sLine = _tHistory[nHistoryPos]
nPos = string.len( sLine )
else
sLine = ""
nPos = 0
end
redraw()
end
elseif param == keys.backspace then
-- Backspace
if nPos > 0 then
redraw(" ");
sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
nPos = nPos - 1
redraw()
end
elseif param == keys.home then
-- Home
nPos = 0
redraw()
elseif param == keys.delete then
if nPos < string.len(sLine) then
redraw(" ");
sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
redraw()
end
elseif param == keys["end"] then
-- End
nPos = string.len(sLine)
redraw()
end
end
end
term.setCursorBlink( false )
term.setCursorPos( w + 1, sy )
print()
return sLine
end
This is a bit too complicated for me
GopherAtl, on 30 December 2012 - 04:26 AM, said:
function readLen(prompt, minLen,maxLen,isPassword)
while true do
write(prompt)
--//read the line; if isPassword is true, pass "*" as the char to display, otherwise nil so it displays what's typed
local sInput=read(isPassword and "*" or nil)
--//if the length is less than min or greater than max...
if #sInput<minLen or #sInput>maxLen then
--//...complain
print("Must be between "..minLen.." and "..maxLen.." characters long!")
else --//not too long or short, return it
return sInput
end
end
end
--//just call it instead of read, passing the prompt, min and max lengths, and optionally "true" if you're reading a password
local username=readLen("Enter username : ",1,16)
--//declare a var for the password before the loop
local password
--//quick loop
while true do
password=readLen("Enter password : ",4,16,true)
--//local declared inside loop, will go away when the loop ends
local pw2=readLen("Confirm password : ",4,16,true)
--//see if they match
if pw2==password then
break --//pws match, end the while loop
end
print("Passwords don't match! Try again")
end
:edit: or, you could modify the original read function grabie posted, if checking after and forcing re-entry bothers you.
This will do just fine and isn't too complicated, thanks.
#6
Posted 30 December 2012 - 04:44 AM
remiX, on 30 December 2012 - 04:38 AM, said:
I have one somewhere on my pc, i'll try find it now, else I'll make a quick one
If you mean that it doesn't allow more than 10 (or more,less) chars to be imputed and doesn't allow any more than it would be perfect if you could post it.
Thanks.
#7
Posted 30 December 2012 - 05:18 AM
str=(#str>10 and string.sub(str,1,10) or str)
to trim it to 10 chars
#8
Posted 30 December 2012 - 05:20 AM
I didn't have time to test it after taking it out of an old file of mine, but try it:
x, y = term.getSize()
function limitRead(nLimit, replaceChar)
term.setCursorBlink(true)
local cX, cY = term.getCursorPos()
local rString = ""
if replaceChar == "" then replaceChar = nil end
while true do
local xPos, yPos = term.getCursorPos()
local event, p1 = os.pullEvent()
if event == "char" then
-- Character event
if #rString + 1 <= nLimit then
rString = rString .. p1
if not replaceChar then
if not nLimit then
write(p1)
else
if #rString >= nLimit then
term.setCursorPos(cX, cY)
write(string.sub(rString, #rString - nLimit + 1))
elseif #rString < nLimit then
write(p1)
end
end
else
if not nLimit then
write(replaceChar)
else
if #rString >= nLimit then
term.setCursorPos(cX, cY)
write(string.rep(replaceChar, nLimit))
elseif #rString < nLimit then
write(replaceChar)
end
end
end
end
elseif event == "key" and p1 == keys.backspace then
-- Backspace
rString = string.sub(rString, 1, #rString-1)
term.setCursorPos(cX, cY)
term.clearLine()
if replaceChar then
for i = 1, #rString do write(replaceChar) end
else
write(rString)
end
elseif event == "key" and p1 == keys.enter then
-- Enter
break
end
end
term.setCursorBlink(false)
print() -- Skip to the next line after clicking enter.
return rString
end
-- And you call it like this
input = limitRead(10)
-- If you want to replace it with a char, like read() then
password = limitRead(10, "*")
#9
Posted 30 December 2012 - 05:43 AM
local function readN(len, replaceChar)
len = len or 10
local input=""
local key = 0
term.setCursorBlink(true)
repeat
local e,p1 = os.pullEvent()
if e=="char" then
if #input < len then
input = input .. p1
term.write(replaceChar or p1)
end
elseif e=="key" and p1==keys.backspace and #input > 0 then
input = input:sub(1,#input-1)
local x,y = term.getCursorPos()
term.setCursorPos(x-1,y)
term.write(" ")
term.setCursorPos(x-1,y)
end
until p1==keys.enter
term.setCursorBlink(false)
return input
end
Edit: it's not the same as the previous ones except for remiX's. The main difference is that he writes the entire string on each iteration, while I handle each position seperately. Also, for unlimited length, you could just use math.huge or term.getSize() instead of adding seperate conditions. For replaceChar a simple 'or' is sufficient.
#10
Posted 31 December 2012 - 03:10 AM
remiX, on 30 December 2012 - 05:20 AM, said:
I didn't have time to test it after taking it out of an old file of mine, but try it:
x, y = term.getSize() function limitRead(nLimit, replaceChar) term.setCursorBlink(true) local cX, cY = term.getCursorPos() local rString = "" if replaceChar == "" then replaceChar = nil end while true do local xPos, yPos = term.getCursorPos() local event, p1 = os.pullEvent() if event == "char" then -- Character event if #rString + 1 <= nLimit then rString = rString .. p1 if not replaceChar then if not nLimit then write(p1) else if #rString >= nLimit then term.setCursorPos(cX, cY) write(string.sub(rString, #rString - nLimit + 1)) elseif #rString < nLimit then write(p1) end end else if not nLimit then write(replaceChar) else if #rString >= nLimit then term.setCursorPos(cX, cY) write(string.rep(replaceChar, nLimit)) elseif #rString < nLimit then write(replaceChar) end end end end elseif event == "key" and p1 == keys.backspace then -- Backspace rString = string.sub(rString, 1, #rString-1) term.setCursorPos(cX, cY) term.clearLine() if replaceChar then for i = 1, #rString do write(replaceChar) end else write(rString) end elseif event == "key" and p1 == keys.enter then -- Enter break end end term.setCursorBlink(false) print() -- Skip to the next line after clicking enter. return rString end -- And you call it like this input = limitRead(10) -- If you want to replace it with a char, like read() then password = limitRead(10, "*")
Orwell, on 30 December 2012 - 05:43 AM, said:
local function readN(len, replaceChar)
len = len or 10
local input=""
local key = 0
term.setCursorBlink(true)
repeat
local e,p1 = os.pullEvent()
if e=="char" then
if #input < len then
input = input .. p1
term.write(replaceChar or p1)
end
elseif e=="key" and p1==keys.backspace and #input > 0 then
input = input:sub(1,#input-1)
local x,y = term.getCursorPos()
term.setCursorPos(x-1,y)
term.write(" ")
term.setCursorPos(x-1,y)
end
until p1==keys.enter
term.setCursorBlink(false)
return input
end
Edit: it's not the same as the previous ones except for remiX's. The main difference is that he writes the entire string on each iteration, while I handle each position seperately. Also, for unlimited length, you could just use math.huge or term.getSize() instead of adding seperate conditions. For replaceChar a simple 'or' is sufficient.
Both of them are working perfect, thanks everyone.
Edit: remiX you have a little problem in your code because if I press backspace no matter where it will erase everything that is behind the input.
Orwell's code doesn't have this bug.
#11
Posted 31 December 2012 - 05:27 AM
exploder, on 31 December 2012 - 03:10 AM, said:
Edit: remiX you have a little problem in your code because if I press backspace no matter where it will erase everything that is behind the input.
Orwell's code doesn't have this bug.
Well, like I said I hadn't tested it or used it in a while
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











