Re: How to read one character at a time without enter pressing



On Jun 6, 2:32 am, "slebet...@xxxxxxxxx" <slebet...@xxxxxxxxx> wrote:
On Jun 6, 12:08 am, Uwe Klein <uwe_klein_habertw...@xxxxxxxxxxx>
wrote:





Cris wrote:
I need an interactive shell programm. It must read one character as
command
and process it immediately without enter pressing.

I try to do it in this way:

fconfigure stdin -buffering none
set var [read stdin 1]

but its not working. In TCL FAQ I found this link on solution:
ftp://ftp.neosoft.com/pub/tcl/alcatel/code/binary-io-hack.shar.gz
but it doesn't work.

Maybe somebody have this file or know better solution?

If you are on a unixy platform:
#!/usr/bin/tclsh

exec stty raw <@ stdin

while {![eof stdin]} {
set char [ read stdin 1 ]
puts stderr char:$char
if { "$char" == "\004" } break
if { "$char" == "\003" } break

}

exec stty -raw <@ stdin

uwe

Though it may work, the correct way (IMHO) to use [eof] is:

while 1 {
set char [ read stdin 1 ]
if {[eof stdin]} break

puts stderr char:$char
if { "$char" == "\004" } break
if { "$char" == "\003" } break
}

otherwise you'll process an extra character on the final read.
Unimportant and ignorable for some code but can possibly lead to
subtle bugs.- Hide quoted text -

- Show quoted text -

AIUI, eof will only return true _after_ the last succesful read. So
the code you posted above will miss the last character:
1) read will get the last character and set eof
2) eof will break from the loop
3) the last character will not be processed.

I would probably write this as:

while {![eof stdin] {
set char [ read stdin 1 ]

puts stderr char:$char
if { "$char" == "\004" } break
if { "$char" == "\003" } break
}

This will terminate the loop after the last character has been read
and handled.

Mark

.



Relevant Pages