【问题标题】:Reading something from a file and putting it under a data type从文件中读取某些内容并将其置于数据类型下
【发布时间】:2010-11-12 13:37:18
【问题描述】:

我有一个包含以下内容的文件:

(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
...
...

我希望我的程序从文件中读取一行,将 (Float,Float,Float) 放入三元组,将“sometext”放入一个字符串,并将所有这些都放在一个新的数据类型下,这样整个事情就会看起来像这样:

SomeDataType (Float,Float,Float) "sometext"

到目前为止我得到了这个:

readFromDisc filePath = do 
                        fileHandle <- openFile "/tmp/lala.txt" ReadMode
                        contents <- hGetContents fileHandle
                        putStrLn $ readOneLine contents

如果文件包含这个:

(5.0,6.0,7.0)"faraway"
(8.0,9.0,0.0)"holdon"

我明白了:

"(5.0,6.0,7.0)\"faraway\""

现在,因为我把它作为一个字符串,我正在考虑使用

breakInput input = break (=='"') input

要得到这个:

("(5.0,6.0,7.0)","\"faraway\"")

这是一对字符串,我打算用一些东西来解析三元组和其中的文本,但感觉都不对。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: parsing haskell file-io io


    【解决方案1】:

    使用reads 函数。它将在字符串的开头解析匹配的部分,并返回字符串的其余部分。

    parseLine :: String -> [((Double, Double, Double), String)]
    parseLine line = do
      (tuple, line') <- reads line
      (string, _)    <- reads line'
      return (tuple, string)
    
    -- parseLine "(5.0, 6.0, 7.0)\"faraway\"" ---> ((5.0, 6.0, 7.0), "faraway")
    

    这将返回一个匹配列表,并忽略行尾的垃圾。由于您的特定案例具有明确的解析,因此成功解析只会产生一个匹配项。

    【讨论】:

    • +1。但是使用Double 而不是Int。还要使解决方案完整:使用lines 拆分成行更容易。一切都是一条线:return . map parseLine . lines =&lt;&lt; readFile "r.txt".
    • @jetxee 感谢您完成解决方案。我修复了类型签名。
    • 你也应该认真考虑 Parsec,如果它更复杂的话。
    【解决方案2】:
    readThat (triple, str) = SomeDataType (read triple :: (Float, Float, Float)) 
                                          (read str :: String)
    

    又快又脏。

    【讨论】:

      【解决方案3】:

      快速破解,如果您不关心处理错误:

      data SomeDataType = SomeDataType (Float, Float, Float) String
                        deriving Read
      
      readOneLine s = read ("SomeDataType " ++ s)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-01
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多