1

我正在编写一个程序,它将文本文件列表作为参数并输出一个文件,其中每一行是文件中相应行之间的选项卡的插入。

假设所有字符都是 ASCII 编码的

import GHC.IO.Handle
import System.IO
import System.Environment
import Data.List

main = do
    (out:files) <- getArgs
    hs <- mapM (`openFile` ReadMode) files
    txts <- mapM B.hGetContents hs
    let final = map (B.intercalate (B.singleton '\t')) . transpose 
                . map (B.lines . B.filter (/= '\t')) $ txts
    withFile out WriteMode $ \out -> 
        B.hPutStr out (B.unlines final)
    putStrLn "Completed successfully"

问题是它输出:

file1row1
    file2row1
file1row2
    file2row2
file1row3
    file2row3

代替:

file1row1    file2row1
file1row2    file2row2
file1row3    file2row3

通过在 ghci 中手动定义函数进行测试时,相同的逻辑可以正常工作。Data.Text.Lazy当使用而不是惰性Bytestrings时,相同的代码可以正常工作。

我的方法有什么问题?

4

2 回答 2

2

Data.ByteString.Lazy.UTF8 中存在一个已知错误,其中换行符转换不会正确进行,即使文档说应该这样做。(请参阅Windows 上的 Data.ByteString.Lazy.Char8 换行符转换——文档是否具有误导性?)这可能是您的问题的原因。

于 2014-03-04T04:05:18.890 回答
2

当我在示例字符串上测试 Data.ByteString.Lazy.UTF8.lines 时,它没有删除 '\r'....

ghci -XOverloadedStrings

> import Data.ByteString.Lazy.UTF8 as B

> B.lines "ab\n\rcd"
  ["ab","\rcd"]

> B.lines "ab\r\ncd"
  ["ab\r","cd"]

我猜这是你的问题。

(为了验证,您可以使用“xxd”或任何其他十六进制编辑器查看输出......查看额外字符是否实际上是“\r”)。

于 2014-03-04T01:24:48.923 回答