0

在 tcl 中执行刷新以捕获用户输入时,有没有办法忽略退格?

我正在执行一个函数,我在一个变量中捕获用户输入,以便稍后在另一个命令中使用。所以我执行以下功能。

puts -nonewline "What is the username? "
flush stdout
set usrnm [gets stdin]

因此,假设使用该命令,只要我不使用退格,一切都会按照我期望的方式工作,但是如果我确实使用退格,则会添加“\x7F”作为字符。有没有办法让退格不被视为一个字符?

4

2 回答 2

0

这似乎取决于您的终端;当我使用这些键序列尝试该代码时:

  • BackspaceabcReturn
  • abcBackspacedReturn

然后在这两种情况下,我都会在变量中得到一个长度为 3 的字符串(通过 测量string length) 。usrnm当终端正确处于熟模式(通常的默认值)时,这是我所期望的。由于 a\x7f可能不是用户名中的有效字符,我猜你可以过滤掉它:

set usrnm [string map {\x7f ""} $usrnm]

绝对确定字符不存在的唯一方法是将终端置于原始模式(也可能无回显)并自己进行所有字符输入处理。相对于问题的规模而言,这是一项巨大的工作。后置过滤器对我来说似乎更明智(我仍然想知道你的终端是怎么回事)。


[编辑]:要将终端恢复到熟模式,请执行以下操作:

exec stty -raw <@stdin
于 2013-03-14T14:37:44.893 回答
0

我最近遇到了这个问题,我写了一个程序来处理 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
}
于 2014-08-14T14:45:08.943 回答