Haskell 中的 '\b' 字符如何工作?
How does the '\b' character in Haskell work?
来源:赫顿,格雷厄姆。 “在 Haskell 中编程”(第 180 页)
- Using
getCh
, define an action readLine :: IO String
that behaves in the same way as getLine, except that it also permits the delete key to be used to remove characters.
Hint: the delete character is ’\ DEL’
, and the control character for moving the cursor back one space is ’\b’
.
我用一个 '\b'
字符解决了这个练习,但在网上发现求解器使用了两个字符。为什么这个问题的求解器使用 "\b \b"
而不是 "\b"
?似乎是一个错字,但我不确定。我发现它适用于三个 '\b'
个字符。
这个角色如何运作?
import System.IO
getCh :: IO Char
getCh = do
hSetEcho stdin False
x <- getChar
hSetEcho stdin True
return x
readLine :: IO String
readLine = readLine' ""
readLine' :: String -> IO String
readLine' xs = do
x <- getCh
case x of
'\n' -> do
putChar '\n'
return xs
'\DEL' ->
if null xs
then readLine' ""
else do
putStr "\b \b"
readLine' (init xs)
_ -> do
putChar x
readLine' (xs ++ [x])
\b
将光标向后移动一个字符,但不会将其删除(至少在大多数终端上不会)。例如,字符串 abcde\b
将显示为 abcde
,而字符串 abcde\bf
将显示为 abcdf
。这就是为什么序列 \b \b
明确地用 space 覆盖最后一个字符,然后再次将光标移回。
如果您只使用 "\b"
,光标会向左移动,但不会删除那里看到的字符,直到您用新的键输入覆盖它。比如FOO←会结束你up with fo⁁o
,但这是误导:如果你 不 按下另一个字母键,但立即按下 ↵,那么看起来结果仍然是 foo
,而实际上它只是 fo
.
为了避免这种情况,解决方案"\b \b"
向左移动,用space覆盖字符以可视化删除它,然后立即再次向左移动。这与向左移动一次并就地删除字符具有相同的效果。
来源:赫顿,格雷厄姆。 “在 Haskell 中编程”(第 180 页)
- Using
getCh
, define an actionreadLine :: IO String
that behaves in the same way as getLine, except that it also permits the delete key to be used to remove characters.
Hint: the delete character is
’\ DEL’
, and the control character for moving the cursor back one space is’\b’
.
我用一个 '\b'
字符解决了这个练习,但在网上发现求解器使用了两个字符。为什么这个问题的求解器使用 "\b \b"
而不是 "\b"
?似乎是一个错字,但我不确定。我发现它适用于三个 '\b'
个字符。
这个角色如何运作?
import System.IO
getCh :: IO Char
getCh = do
hSetEcho stdin False
x <- getChar
hSetEcho stdin True
return x
readLine :: IO String
readLine = readLine' ""
readLine' :: String -> IO String
readLine' xs = do
x <- getCh
case x of
'\n' -> do
putChar '\n'
return xs
'\DEL' ->
if null xs
then readLine' ""
else do
putStr "\b \b"
readLine' (init xs)
_ -> do
putChar x
readLine' (xs ++ [x])
\b
将光标向后移动一个字符,但不会将其删除(至少在大多数终端上不会)。例如,字符串 abcde\b
将显示为 abcde
,而字符串 abcde\bf
将显示为 abcdf
。这就是为什么序列 \b \b
明确地用 space 覆盖最后一个字符,然后再次将光标移回。
如果您只使用 "\b"
,光标会向左移动,但不会删除那里看到的字符,直到您用新的键输入覆盖它。比如FOO←会结束你up with fo⁁o
,但这是误导:如果你 不 按下另一个字母键,但立即按下 ↵,那么看起来结果仍然是 foo
,而实际上它只是 fo
.
为了避免这种情况,解决方案"\b \b"
向左移动,用space覆盖字符以可视化删除它,然后立即再次向左移动。这与向左移动一次并就地删除字符具有相同的效果。