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

Limit Max read() chars

Started by 3ydney, 09 March 2013 - 01:06 AM
3ydney #1
Posted 09 March 2013 - 02:06 AM
How can I limit how many chars can be typed using a read() function??

Thanks in Advance
- Adam
theoriginalbit #2
Posted 09 March 2013 - 02:38 AM
Write your own read function.
LordIkol #3
Posted 09 March 2013 - 03:00 AM
very simple workaround.
for a complex function you woul have to look at os.pullEvent




function maxread(len)
print "please enter Text"
mytext = read()
if  #mytext > len then
while #mytext > len do
print ("maximum number of chars is " ..len)
mytext = read()
end
else
return mytext
end
end

test = maxread(5)
print(test)

@Edit: Changed the code a bit. its still not very userfriendly but at least without recursion ;)/>
Edited on 09 March 2013 - 03:12 AM
theoriginalbit #4
Posted 09 March 2013 - 03:05 AM
very simple workaround.
for a complex function you woul have to look at os.pullEvent



function maxread(len)
print "Bitte text eingeben"
mytext = read()
if #mytext > len then
print ("maximum number of chars is " ..len)
maxread(len)
end
end

maxread(5)
That wouldn't quite work. you would need a loop in there to force it to read again when its not equal. however, from a usability point of view it would be better to just stop them from entering more text, over expecting them to count out how many they have used.
LordIkol #5
Posted 09 March 2013 - 03:28 AM
very simple workaround.
for a complex function you woul have to look at os.pullEvent



function maxread(len)
print "Bitte text eingeben"
mytext = read()
if #mytext > len then
print ("maximum number of chars is " ..len)
maxread(len)
end
end

maxread(5)
That wouldn't quite work. you would need a loop in there to force it to read again when its not equal. however, from a usability point of view it would be better to just stop them from entering more text, over expecting them to count out how many they have used.

Why i need a loop when the function calls itself when the if statement is true?
for the usability you are absolutely right. just wanted to show a simple option and point into a direction for more complex way.
remiX #6
Posted 09 March 2013 - 03:31 AM
A lot of people have asked this… Try searching…
Grim Reaper #7
Posted 09 March 2013 - 03:41 AM
Here's a function that I wrote for a similar question quite a while ago:



function limitRead( nLength, cReplaceChar )
    term.setCursorBlink( true )

    nLength = nLength or -1 -- -1 is unlimited
    sReturnString = ""

    xPos, yPos = term.getCursorPos()

    while true do
        event, char = os.pullEvent()

        if nLength ~= -1 and string.len( sReturnString ) >= nLength then term.setCursorBlink( false ); return sReturnString end -- Length check

        if event == "char" then sReturnString = sReturnString .. char
        elseif event == "key" and char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
        elseif event == "key" and char == 14 then -- Backspace
            term.setCursorPos( xPos, yPos )
            term.write( string.rep( " ", string.len( sReturnString ) ) )
            sReturnString = string.sub( sReturnString, 1, string.len( sReturnString )-1 )
            term.setCursorPos( xPos, yPos )

            if not cReplaceChar then term.write( sReturnString )
            else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
        end

        term.setCursorPos( xPos, yPos )
        term.write( string.rep( " ", string.len( sReturnString ) ) )
        term.setCursorPos( xPos, yPos )
        if not cReplaceChar then term.write( sReturnString )
        else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
    end
end
theoriginalbit #8
Posted 09 March 2013 - 03:42 AM
Why i need a loop when the function calls itself when the if statement is true?
for the usability you are absolutely right. just wanted to show a simple option and point into a direction for more complex way.
Calling the function instead of using a loop causes problems. you can fill the program stack and get a 'java vm IndexOutOfBoundsException 255'. you should never use recursion unless it is 100% required, here it is not. also, you may call the function, but you never actually return the value it reads, which is another issue, its a fairly useless read function if it cannot return what it has read.
LordIkol #9
Posted 09 March 2013 - 03:56 AM
Hi Bit,

Thanks for the Answer, again learned sth new.
will keep this in mind for the future.
But there is still a lot to learn :)/>

@Edit removed recursion from code above and added return value. Still faaar away from elegant, but at least with less error potential :D/>

Best Regards
Loki
ChunLing #10
Posted 09 March 2013 - 08:02 AM
You can also use a recursion when the depth of the recursion is naturally limited. The problem is when it is entirely possible (or inevitable) for the recursion to continue until the stack overflows, as is the case where a recursion is used in place of a loop.
remiX #11
Posted 09 March 2013 - 08:11 AM
Made this a while back …
function limitRead(nLimit, replaceChar)
	term.setCursorBlink(true)
	local cX, cY = term.getCursorPos()
	local rString = ""
	if replaceChar == "" then replaceChar = nil end
	repeat
		local event, p1 = os.pullEvent()
		if event == "char" then
			-- Character event
			if #rString + 1 <= nLimit then
				rString = rString .. p1
				write(replaceChar or p1)
			end
		elseif event == "key" and p1 == keys.backspace and #rString >= 1 then
			-- Backspace
			rString = string.sub(rString, 1, #rString-1)
			xPos, yPos = term.getCursorPos()
			term.setCursorPos(xPos-1, yPos)
			write(" ")
			term.setCursorPos(xPos-1, yPos)
		end
	until event == "key" and p1 == keys.enter
	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, "*")
theoriginalbit #12
Posted 09 March 2013 - 03:07 PM
You can also use a recursion when the depth of the recursion is naturally limited. The problem is when it is entirely possible (or inevitable) for the recursion to continue until the stack overflows, as is the case where a recursion is used in place of a loop.
Exactly, when you have a condition for it to finish (and that condition has it run in less calls than the stack) then its fine. Hell try to iterate a file system or solve Towers of Hanoi without using recursion! Sometimes it is just needed!