【问题标题】:Why does my Haskell program not accept standard input redirection?为什么我的 Haskell 程序不接受标准输入重定向?
【发布时间】:2017-04-20 01:54:44
【问题描述】:

我试图通过提供文件名作为命令行参数来读取 Haskell 中的文件。 我读到您可以通过以下方式完成此操作:

./program < input.txt

我写了这段代码:

main = do
    [fileName] <- getArgs
    file <- readFile fileName
    print file

但我收到此错误:“do 表达式中的模式匹配失败”。如果我省略它的

【问题讨论】:

  • &lt; 符号与 Haskell 完全无关——它是“管道”运算符,它(由您的 shell 实现,并且)将一个程序的输出作为 输入 (不是命令行参数)到另一个程序。您的 Haskell 程序希望始终接收一个参数,因此会崩溃。
  • @user2407038 其实&lt;不是一个shell管道,它只是输入重定向。 ls -l | grep foo 将是一个管道。

标签: haskell terminal command-line-arguments readfile


【解决方案1】:

./program &lt; input.txt 使用 0 个参数调用程序并将标准输入重定向到 input.txt 的内容。

所以你得到一个模式匹配错误,因为getArgs 是空的。因此,如果您希望您的程序始终从标准输入读取,请不要使用命令行参数,而是从标准输入读取而不是从文件读取。

如果您希望程序仅在没有给出文件名的情况下从标准输入读取,请先检查参数的长度,然后根据给定的文件名或标准输入读取。

【讨论】:

  • 谢谢! :D 现在我使用了 file
  • 不检查长度;模式匹配。
  • 好吧,在这种情况下,模式匹配是检查参数长度的最佳方法。我不会说我们检查长度。
【解决方案2】:

如果您运行./program arg,则arg 作为参数传递。标准输入保持默认——通常从终端从键盘读取。

如果您运行./program &lt; filename,则不会向程序传递任何参数。标准输入现在被重定向,以便从文件 filename 中读取。

这就是 OS shell 的工作原理。

在 Haskell 中,getArgs 获取程序参数。在第二种情况下,它们是空的,[fileName] &lt;- getArgs 因运行时错误而失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多