在tcl中执行刷新以捕获用户输入时是否有方法忽略退格?
我正在执行一个函数,在这个函数中,我在一个变量中捕获用户输入,以便稍后在另一个命令中使用。所以我执行以下函数:
puts -nonewline "What is the username? "
flush stdout
set usrnm [gets stdin]
那么让我们说使用这个命令,只要我不使用退格,一切都按照我期望的方式工作,但是如果我使用退格,一个"x7F"被添加为一个字符。是否有一种方法可以使退格不被视为字符?
这似乎取决于您的终端;当我用这些键序列尝试代码时:
- 退格 的 b c 返回
- b c 退格 d 返回
然后在两种情况下,我在usrnm
变量中得到长度为3的字符串(通过string length
测量)。这是当终端正确地处于熟透模式(通常的默认模式)时我所期望的。由于x7f
可能不是用户名中的有效字符,我猜您可以将其过滤掉:
set usrnm [string map {x7f ""} $usrnm]
确保绝对不存在字符的唯一方法是将终端置于原始模式(可能也没有回显)并自己执行所有字符输入处理。相对于问题的规模,这是巨大的工作量;对我来说,后滤镜似乎更明智(我仍然想知道你的终端是怎么回事)。
[EDIT]:要将终端重新设置为熟透模式,请执行:
exec stty -raw <@stdin
我最近刚刚遇到这个问题,我写了一个过程来处理char 127字符(退格)。如果需要进行任何其他输入清理,也可以在这里执行,例如删除特殊字符。我有一种感觉,这可以更优雅,但它确实工作。
proc cleanInput {str} {
set return ""
for {set i 0} {$i < [string length $str]} {incr i} {
set char [string index $str $i]
set asc [scan $char %c]
if {$asc == 127} { #backspace
if {[string length $return] > 0} {
set return [string range $return 0 [expr "[string length $return] - 2"]]
}
} else {
append return $char
}
}
return $return
}