Haskell ';getLine';未按预期工作,被跳过

Haskell ';getLine';未按预期工作,被跳过,haskell,Haskell,我是Haskell的新手,正在编写一些简单的文本/文件操作函数。我当前正在尝试在将字符串添加到文件之前修改它 我有一个函数“insertChar”,它在字符串中的任何给定位置添加一个字符(使用Haskell中99个问题中问题21的解决方案) 我见过这堆溢出柱 并试图遵循该答案,将代码更改为 import System.Environment import System.Directory import System.IO (hSetBuffering, stdin, BufferMo

我是Haskell的新手,正在编写一些简单的文本/文件操作函数。我当前正在尝试在将字符串添加到文件之前修改它

我有一个函数“insertChar”,它在字符串中的任何给定位置添加一个字符(使用Haskell中99个问题中问题21的解决方案)

我见过这堆溢出柱

并试图遵循该答案,将代码更改为

import System.Environment   
import System.Directory   
import System.IO (hSetBuffering, stdin, BufferMode(NoBuffering)) *New line*
import Data.List  

main :: IO ()
main = do 
      hSetBuffering stdin NoBuffering *New line*
      putStrLn "Insert a string"
      word <- getLine
      putStrLn "Insert a char"
      char <- getChar
      putStrLn "Insert a position"
      pos <- getLine 
      let x = (read pos :: Int) 
      putStrLn "Adding char to list..."
      let newS = [(insertChar char word x)] 
      putStrLn "Printed list: "
      print (newS)
      putStrLn "Insert file name"
      file <- getLine
      putStrLn "Adding new string to file..."
      add file newS

insertChar :: a -> [a] -> Int -> [a]
insertChar x ys     1 = x:ys
insertChar x (y:ys) n = y:insertChar x ys (n-1)

add :: String -> [String] -> IO ()  
add fileName [item] = appendFile fileName item
导入系统环境
导入系统目录
import System.IO(hSetBuffering、stdin、BufferMode(NoBuffering))*新行*
导入数据。列表
main::IO()
main=do
hSetBuffering stdin NoBuffering*新行*
putStrLn“插入字符串”
字[字符串]->IO()
添加文件名[项目]=追加文件名项目

但是,它仍然会产生相同的错误。知道我做错了什么吗?

多亏了威廉·范·昂森对我最初问题的评论,我终于找到了解决办法。我在“putStrLn”Insert a position”一行之后添加了一个“getLine”,因此代码现在如下所示

import System.Environment   
import System.Directory  
import System.IO 
import Data.List  

main :: IO ()
main = do 
      putStrLn "Insert a string"
      word <- getLine
      putStrLn "Insert a char"
      char <- getChar
      putStrLn "Insert a position"
      temp <- getLine *line that has been added*
      pos <- getLine
      let x = (read pos :: Int)
      putStrLn "Adding char to list..."
      let newS = [(insertChar char word x)]
      putStrLn "Printed list: "
      print (newS)
      putStrLn "Insert file name"
      file <- getLine
      putStrLn "Adding new string to file..."
      add file newS

insertChar :: a -> [a] -> Int -> [a]
insertChar x ys     1 = x:ys
insertChar x (y:ys) n = y:insertChar x ys (n-1)

add :: String -> [String] -> IO ()  
add fileName [item] = appendFile fileName item
导入系统环境
导入系统目录
导入系统.IO
导入数据。列表
main::IO()
main=do
putStrLn“插入字符串”
单词IO()
添加文件名[项目]=追加文件名项目

您导入了正确的东西,但从未真正调用过它!试试这个:

main = do
    hSetBuffering stdin NoBuffering
    -- ...all the rest of your original main, exactly as it used to be

这样,当它到达
getChar
行时,只要您按下一个键,它就会从
getChar
返回,而不是等到您按下enter键。用户界面将更有意义,代码也将更有意义,因为您不需要吞下用户实际上并不想输入的虚幻换行符。

因为您使用了
getChar
,光标只需放在该字符之后。您可能希望在标记的行之前添加一个
getLine
,以便将光标首先放在下一行。@MichaelLitchard我已删除图像并将输出包含在文本中format@user10731678谢谢。:)我删除了downvote。您链接到的问题与您的问题具有完全相同的根本原因,但实际上没有应用链接中建议的修复@我会的!如问题中所述,这对我不起作用。我也试着像你在这里建议的那样把它放在我的主要功能中,但它却关闭了GHCIcompletely@user10731678哇!现在,这值得一个新的问题,如果它可以可靠地复制。包括关闭ghci的代码,以及加载/运行代码所做的确切操作。我似乎无法复制ghci关闭(不确定为什么?),但是删除“temp->getLine”并将“hSetBuffering stdin NoBuffering”放在我的主函数中,并将其导入顶部会创建原始problem@Seb我不能复制。删除您的评论后,添加
hSetBuffering
行,并调用
runhaskell test.hs
,当我键入
foo
,然后输入enter,然后输入
I
(然后不输入!),它立即开始向我询问职位;输入
3
,然后输入enter将导致打印
[“foio”]
。如果我在
ghci test.hs
中代替键入
main
(并按enter键),而不是使用
runhaskell
,也会发生同样的情况。你能详细描述一下你正在采取的行动的顺序和它所显示的行为吗?我已经编辑了上面的问题,以显示我使用“hSetBuffering stdin NoBuffering”所做的事情。我通过GHCI运行它,首先加载它,然后运行“main”函数:l TextEditor.hs,然后是“main”(如问题的错误部分所示)。它仍然跳过用户可以输入位置的行
import System.Environment   
import System.Directory  
import System.IO 
import Data.List  

main :: IO ()
main = do 
      putStrLn "Insert a string"
      word <- getLine
      putStrLn "Insert a char"
      char <- getChar
      putStrLn "Insert a position"
      temp <- getLine *line that has been added*
      pos <- getLine
      let x = (read pos :: Int)
      putStrLn "Adding char to list..."
      let newS = [(insertChar char word x)]
      putStrLn "Printed list: "
      print (newS)
      putStrLn "Insert file name"
      file <- getLine
      putStrLn "Adding new string to file..."
      add file newS

insertChar :: a -> [a] -> Int -> [a]
insertChar x ys     1 = x:ys
insertChar x (y:ys) n = y:insertChar x ys (n-1)

add :: String -> [String] -> IO ()  
add fileName [item] = appendFile fileName item
main = do
    hSetBuffering stdin NoBuffering
    -- ...all the rest of your original main, exactly as it used to be