F#是否有类似C++ flush(stdin)的清缓冲区方法?点餐系统输入问题求助
问题原因分析
- 核心逻辑位置错误
你当前的loop()函数仅实现了输出提示的功能,读取用户输入、判断是否继续的代码是写在全局作用域的,只会在程序启动时执行1次,后续调用loop()时不会再触发输入读取和条件判断。另外你的提示文本里pruchase为拼写错误,正确拼写为purchase,该问题不影响核心逻辑运行。 - 执行流程无分支控制
你在调用loop()之后直接写了输出感谢信息的代码,没有根据用户选择的结果做分支跳转,不管用户输入什么内容,都会继续执行后续的感谢输出逻辑,没有实现继续点餐的循环。
对应修复方案
首先调整loop()函数,把输入读取、判断逻辑都封装到函数内,返回布尔值标识用户是否要继续点餐,再调整整体代码的循环结构,示例修改后的核心代码:
open System // 清空输入缓冲区的方法,等价于C++的flush(stdin) let flushStdin () = while Console.KeyAvailable do Console.ReadKey(true) |> ignore let menu()= printfn "---------------------------------------" printfn " Food ordering system" printfn "---------------------------------------" printfn "1. ORDER FOOD " printfn "2. ORDER DRINK" Console.Write("Enter your selection : ") // 修改后的loop函数,返回是否要继续 let loop()= // 每次读取输入前先清空缓冲区 flushStdin() Console.Write("Do you want to continue purchase?:") let choice = Console.ReadLine().Trim() choice.Equals("y", StringComparison.OrdinalIgnoreCase) let food()= printfn "\n1.MCD CHICKEN RM 10 \n2.FILET-O-FISH RM 13 \n3.FRENCH FRIES RM 5 \n4.APPLE PIE RM 4" Console.Write("\nEnter food code that you want :") let option=Console.ReadLine() Console.Write("How many you want :") let qty=Console.ReadLine() match option with | "1" -> let price = 10 let total = int qty * price printfn $"\nThe price for {qty} set MCD CHICKEN is RM {total}" | "2" -> let price = 13 let total = int qty * price printfn $"\nThe price for {qty} set FILET-O-FISH is RM {total}" | "3" -> let price = 5 let total = int qty * price printfn $"\nThe price for {qty} FRENCH FRIES is RM {total}" | "4" -> let price = 4 let total = int qty * price printfn $"\nThe price for {qty} APPLE PIE is RM {total}" | _ -> printfn "Invalid input" menu() // 调用loop判断是否继续 if loop() then menu() else printfn "\nThank you for your purchase " let drink()= printfn "\n1.ICE BLENDED CHOCOLATE MEDIUM RM 8 \n2.MANGO PEACH RM 11 \n3.PEPSI RM 4 \n4.ICE LEMON TEA RM 4" Console.Write("\nEnter beverage code that you want :") let option=Console.ReadLine() Console.Write("How many you want :") let qty=Console.ReadLine() match option with | "1" -> let price = 8 let total = int qty * price printfn $"\nThe price for {qty} ICE BLENDED CHOCOLATE MEDIUM is RM {total}" | "2" -> let price = 11 let total = int qty * price printfn $"\nThe price for {qty} MANGO PEACH is RM {total}" | "3" -> let price = 4 let total = int qty * price printfn $"\nThe price for {qty} PEPSI is RM {total}" | "4" -> let price = 4 let total = int qty * price printfn $"\nThe price for {qty} ICE LEMON TEA is RM {total}" | _ -> printfn "Invalid input" menu() if loop() then menu() else printfn "\nThank you for your purchase " let rec main()= menu() let selection=Console.ReadLine() if selection = "1" then food() else drink() main()
F#清空输入缓冲区的实现
你需要的类似C++flush(stdin)的功能可以通过循环读取所有待处理按键实现:
- 先通过
Console.KeyAvailable判断输入缓冲区中是否还有未读取的按键 - 循环调用
Console.ReadKey(true)读取所有待处理内容并丢弃,达到清空缓冲区的效果
对应实现代码就是上述示例中的flushStdin函数,可直接复用。
内容的提问来源于stack exchange,提问作者SeanK02
相关产品推荐
相关产品推荐

