2010-11-12 29 views
1

我有一個包含這個文件:讀從文件的東西,並把它的數據類型下

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

,我想我的程序從文件中讀取一條線,把(浮動,浮動,浮動)到一個新的數據類型下特里普爾和「someText」則會爲String和這一切使整個事情是這樣的:

SomeDataType(浮動,浮動,浮動)「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\"") 

這是一對字符串,我打算用一些東西來解析三位一體和文本,但所有這些都不正確。

有沒有更好的方法來做到這一點?

回答

6

使用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") 

這將返回一個匹配列表,並忽略行尾的垃圾。由於您的特定案例具有明確的解析,所以只有一個匹配將通過成功的解析生成。

+3

+1。但是使用'Double'而不是'Int'。同時爲了使解決方案完整:使用'lines'分割線條更容易。一切都是一蹴而就的:'回報。映射parseLine。 lines =「readFile」r.txt「'。 – sastanin 2010-11-12 14:02:51

+0

@jetxee感謝您完成解決方案。我修復了類型簽名。 – Heatsink 2010-11-12 14:22:04

+0

YOu也應該認真考慮Parsec,如果它更復雜。 – fuz 2010-11-13 07:20:15

0
readThat (triple, str) = SomeDataType (read triple :: (Float, Float, Float)) 
             (read str :: String) 

快速而骯髒。

0

快速破解,如果你不關心錯誤處理:

data SomeDataType = SomeDataType (Float, Float, Float) String 
        deriving Read 

readOneLine s = read ("SomeDataType " ++ s)