0

ユーザー入力をキャプチャするために tcl でフラッシュを実行するときにバックスペースを無視する方法はありますか?

後で別のコマンドで使用する変数にユーザー入力をキャプチャする関数を実行しています。だから私は次の機能を実行します。

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

したがって、バックスペースを使用しない限り、そのコマンドを使用すると、すべてが期待どおりに機能するとしますが、バックスペースを使用すると、「\ x7F」が文字として追加されます。バックスペースを文字として扱わない方法はありますか?

4

2 に答える 2

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 に答える
0

それはあなたの端末に依存しているようです。これらのキーシーケンスでそのコードを試すと:

  • BackspaceabcReturn
  • abcBackspacedReturn

次に、どちらの場合も変数に長さ 3 の文字列 ( で測定string length)を取得します。usrnmこれは、端末が適切にクック モード (通常のデフォルト) になっている場合に期待することです。いずれにせよ、 a\x7fはおそらくユーザー名の有効な文字ではないため、フィルターで除外できると思います。

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

文字が存在しないことを完全に確認する唯一の方法は、端末を raw モード (およびおそらくエコーなし) にして、すべての文字入力処理を自分で行うことです。これは、問題のサイズに比べて膨大な量の作業です。ポストフィルターは私にはより賢明なようです(そして、私はまだあなたの端末がどうなっているのか疑問に思っています)。


[編集]: 端末をクック モードに戻すには、次のようにします。

exec stty -raw <@stdin
于 2013-03-14T14:37:44.893 に答える