在 tcl 中执行刷新以捕获用户输入时,有没有办法忽略退格?
我正在执行一个函数,我在一个变量中捕获用户输入,以便稍后在另一个命令中使用。所以我执行以下功能。
puts -nonewline "What is the username? "
flush stdout
set usrnm [gets stdin]
因此,假设使用该命令,只要我不使用退格,一切都会按照我期望的方式工作,但是如果我确实使用退格,则会添加“\x7F”作为字符。有没有办法让退格不被视为一个字符?
在 tcl 中执行刷新以捕获用户输入时,有没有办法忽略退格?
我正在执行一个函数,我在一个变量中捕获用户输入,以便稍后在另一个命令中使用。所以我执行以下功能。
puts -nonewline "What is the username? "
flush stdout
set usrnm [gets stdin]
因此,假设使用该命令,只要我不使用退格,一切都会按照我期望的方式工作,但是如果我确实使用退格,则会添加“\x7F”作为字符。有没有办法让退格不被视为一个字符?
这似乎取决于您的终端;当我使用这些键序列尝试该代码时:
然后在这两种情况下,我都会在变量中得到一个长度为 3 的字符串(通过 测量string length
) 。usrnm
当终端正确处于熟模式(通常的默认值)时,这是我所期望的。由于 a\x7f
可能不是用户名中的有效字符,我猜你可以过滤掉它:
set usrnm [string map {\x7f ""} $usrnm]
绝对确定字符不存在的唯一方法是将终端置于原始模式(也可能无回显)并自己进行所有字符输入处理。相对于问题的规模而言,这是一项巨大的工作。后置过滤器对我来说似乎更明智(我仍然想知道你的终端是怎么回事)。
[编辑]:要将终端恢复到熟模式,请执行以下操作:
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
}