.net - 有没有办法读取 F# 控制台应用程序中特定行上的文本?
问题描述
我想将某行中的文本放入变量中。我能以某种方式使用 Console.CursorLeft 和 Console.CursorTop 来做到这一点吗?程序甚至有可能知道光标当前在哪个字母上?我有一个程序,您可以在其中使用箭头键突出显示某行,但它要求您已经知道该行的内容并重复它。
这是到目前为止的程序,它可以让您了解我正在尝试做的事情。
open System
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 1"
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.White
printfn "Option 2"
printfn "Option 3"
Console.SetCursorPosition(0, 0)
let mutable exit = false
while not exit do
let mutable key = Console.ReadKey()
if key.Key.Equals(ConsoleKey.UpArrow) then
Console.SetCursorPosition(0, Console.CursorTop - 1)
if key.Key.Equals(ConsoleKey.DownArrow) then
Console.SetCursorPosition(0, Console.CursorTop + 1)
if key.Key.Equals(ConsoleKey.Enter) then
let selected = Console.CursorTop + 1
Console.SetCursorPosition(0, 3)
printfn "You selected %i" (selected)
exit <- true
let mutable test = Console.CursorTop
Console.SetCursorPosition(0, 0)
printfn "Option 1"
printfn "Option 2"
printfn "Option 3"
if test = 0 then
Console.SetCursorPosition(0, 0)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 1"
if test = 1 then
Console.SetCursorPosition(0, 1)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 2"
if test = 2 then
Console.SetCursorPosition(0, 2)
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "OPTION 3"
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.White
Console.SetCursorPosition(0, test)
Console.Read() |> ignore
解决方案
鉴于评论中的澄清,我认为绝对没有理由以需要阅读打印到控制台的文本的方式编写应用程序。
如果你这样做了,你将基本上依赖控制台文本来维护应用程序的状态。换句话说,您将状态保持在有限大小的 2D 字符数组中!
更好的方法是使用 F# 类型来表示状态。例如,您可以定义一个记录来保存您的菜单选项、选择以及是否已进行选择的标志:
type State =
{ Options : string list
Selection : int
Completed : bool }
现在您可以定义一个打印状态的函数:
let printMenu menu =
Console.SetCursorPosition(0, 0)
for i, option in Seq.indexed menu.Options do
if i = menu.Selection then
Console.BackgroundColor <- ConsoleColor.White
Console.ForegroundColor <- ConsoleColor.Black
printfn "%s" option
Console.BackgroundColor <- ConsoleColor.Black
Console.ForegroundColor <- ConsoleColor.Gray
还有一个在按下键时计算新状态的函数:
let handleKey (key:ConsoleKeyInfo) state =
match key.Key with
| ConsoleKey.UpArrow -> { state with Selection = state.Selection-1 }
| ConsoleKey.DownArrow -> { state with Selection = state.Selection+1 }
| ConsoleKey.Enter -> { state with Completed = true }
| _ -> state
最后,您可以使用菜单选项定义初始状态。我会保留你的while
循环,所以这将是一个可变变量:
let mutable state =
{ Options = ["Option 1"; "Option 2"; "Option 3"]
Completed = false
Selection = 0 }
主要的应用程序逻辑现在超级简单。只需在state.Completed
为 false 时循环,打印菜单,读取密钥并更新状态:
while not state.Completed do
printMenu state
let key = Console.ReadKey()
state <- handleKey key state
Console.SetCursorPosition(0, 3)
printfn "You selected %i" state.Selection
这种构建应用程序的方式更加清晰,因为它将状态保持在显式数据类型中,并且与对其进行操作的各种函数分开。
推荐阅读
- vue.js - 从 vue.js 中渲染列表中的数组访问数据
- c++ - 可变参数模板限定符
- java - 如何根据 href 链接动态更改 Thymeleaf 片段
- python - Jupyter Notebook 文件似乎保存为 html 而不是 .IPYNB
- python - 每次用户点击页面时 Django 中间件进行记录
- javascript - Sweet alert 2 的自定义样式
- opengl - 根据另一个纹理的亮度,从一个纹理到另一个纹理的平滑渐变过渡
- microsoft-graph-api - 异常 Azure AD B2C 使用 GraphServiceClient 设置自定义属性
- azure-data-factory - 我无法从 Azure 数据工厂中的 Impala 获取数据。通过查询超时异常复制活动
- powershell - 更新列表视图 SharePoint PowerShell