我的文件txt包含两个数字,例如:
2
3
你怎么看,每一行都以点结束。
如何阅读并打印例如这些数字的总和?
如果我的文件不包含点,那么例如我有
2
3
这不是问题。我的代码是:
main3 = do
x <- openFile "C:/Users/file.txt" ReadMode
m <- hGetLine x
n <- hGetLine x
return ((read m::Int)+(read n::Int))
它运作良好。但是当我的文件中有点时,我不知道我能做什么。也许是任何图书馆?
感谢您的帮助。
答案 0 :(得分:5)
问题是read
不会将"3."
解析为3
。如果你只想以一种黑客的方式做到这一点,你可以放弃最后一个角色。
main4 = do
x <- openFile "C:/Users/file.txt" ReadMode
m <- hGetLine x
n <- hGetLine x
return ((read (init m)::Int)+(read (init n)::Int))
可能有效但很脆弱,因为它假定每行中唯一的非数字字符是最后一个。我们可以通过假设我们的数字中的第一个n
数字字符来做得更好
import Data.Char
-- takeWhile isDigit :: String -> String
main5 path = do
f <- readFile path
numberStrings <- map (takeWhile isDigit) (lines f)
sum (map read numberStrings)
最强大的解决方案是升级到像Parsec这样的“解析器组合库”,它可以让你写出文本文件的语法。
答案 1 :(得分:3)
有几种方法可以做到..最简单的是
main = do
text <- readFile "file.txt" -- Grab the file
let nums = map read . map init . lines $ text
print $ sum nums
init
只会丢弃.
。但是我会像这样写
import Text.Parsec.String
import Text.Parsec
import Control.Applicative ((<*), (<$>))
getNums :: Parser [Int]
getNums = num `sepEndBy` newline
where num = read <$> many1 digit <* char '.'
main = parseFromFile getNums "filename" >>= print . fmap sum
是否值得使用parsec这样的东西?答案是“它取决于”。我的经验法则是,如果我计划不止一次使用它,那么只需咬紧牙关并使用parsec。使用像parsec这样的库来修改新的和更复杂的格式会更容易,更容易。另外,您可以通过这种方式获得免费[体面]错误消息。
答案 2 :(得分:0)
您可以通过几个步骤来利用Haskell的monadic API:
当我有时间的时候,我会尝试建立一个例子。使用Haskell的monadic API总是很有趣。