干净的语言:在文件末尾附加数字,fwritei 不起作用
Clean language: append number in end of file, fwritei doesn't work
我正在尝试编写接收文件名 [String]
、文件目录名 String
和 *f
的函数。该函数将在每个文件末尾附加一个整数。
这是我目前得到的:
import StdEnv
import StdFile
import FileManipulation
appendNumInEndOfVmFiles :: [String] String *f -> String
appendNumInEndOfVmFiles [] dirname w = "finished"
appendNumInEndOfVmFiles [x:xs] dirname w
# path = dirname +++ "\\" +++ x
# (ok,file,files) = fopen path FAppendText w
# file = fwritei 12 file
# (ok2,_) = fclose file w
= appendNumInEndOfVmFiles xs dirname w
Start w
// 1. Receive name of directory from the user.
# (io,w) = stdio w // open stdio
# io = fwrites "Enter name of directory:\n" io // ask for name
# (name,io) = freadline io // read in name
# name = name % (0, size name - 2) // remove \n from name
# (ok,w) = fclose io w // close stdio
| not ok = abort "Couldn't close stdio" // abort in case of failure
// 2. Get a list of all file names in that directory.
# (dir,w) = getDirectoryContents (RelativePath [PathDown name]) w
# fileList = getNamesOfFilesInDirectory (getEntriesList dir)
= appendNumInEndOfVmFiles (getVmFiles fileList) name w
假设 getVmFiles
在我的 FileManipulation.dcl
文件中定义,并且在这个问题的上下文中 name
是 "myDir"
并且文件列表是 ["hello.vm","Wiki.vm"]
出于某种原因,即使我在屏幕上看到 "finished" 消息,文件也没有被修改。无论我给 fopen
什么样的整数,即使它的 FWriteText
或 FWriteData
它仍然什么都不做......即使我使用 fwritec
或 fwrites
字符没有任何反应。
我在这里缺少什么?非常感谢!
For some reason, even that I got "finished" message on the screen, the files aren't modified.
这是由于 lazy evaluation。 appendNumInEndOfVmFiles
中没有使用fclose
的结果,所以fclose
不求值。因此,fwritei
也不需要计算。您可以通过在 ok2
:
上添加守卫来解决此问题
# (ok2,_) = fclose file w
| not ok2 = abort "fclose failed\n"
= appendNumInEndOfVmFiles xs dirname w
但是,执行此操作的典型方法是将函数重写为 return 和 *f
而不是 String
,这样这个唯一值就不会丢失。只要使用了结果,那么,fwritei
就被评估了。您可以使 *f
参数严格(即在前面添加 !
)。这将确保在进入函数之前对其进行评估,以便执行所有延迟文件关闭。
您的代码还有一些问题:
这里用了两次w
,是不合法的,因为是严格类型。您应该在守卫中使用 (ok2,w)
以继续相同的环境。
# (ok2,_) = fclose file w
= appendNumInEndOfVmFiles xs dirname w
appendNumInEndOfVmFiles
需要类型上下文 | FileSystem f
来解决 fopen
和 fclose
.
[= 的重载问题52=]
最后:
... even if its FWriteText
or FWriteData
...
如你所知:不同之处在于第一个会以 ASCII 表示形式写入整数,而第二个会将其二进制写入 4 或 8 个字节(取决于系统的位宽)。
我正在尝试编写接收文件名 [String]
、文件目录名 String
和 *f
的函数。该函数将在每个文件末尾附加一个整数。
这是我目前得到的:
import StdEnv
import StdFile
import FileManipulation
appendNumInEndOfVmFiles :: [String] String *f -> String
appendNumInEndOfVmFiles [] dirname w = "finished"
appendNumInEndOfVmFiles [x:xs] dirname w
# path = dirname +++ "\\" +++ x
# (ok,file,files) = fopen path FAppendText w
# file = fwritei 12 file
# (ok2,_) = fclose file w
= appendNumInEndOfVmFiles xs dirname w
Start w
// 1. Receive name of directory from the user.
# (io,w) = stdio w // open stdio
# io = fwrites "Enter name of directory:\n" io // ask for name
# (name,io) = freadline io // read in name
# name = name % (0, size name - 2) // remove \n from name
# (ok,w) = fclose io w // close stdio
| not ok = abort "Couldn't close stdio" // abort in case of failure
// 2. Get a list of all file names in that directory.
# (dir,w) = getDirectoryContents (RelativePath [PathDown name]) w
# fileList = getNamesOfFilesInDirectory (getEntriesList dir)
= appendNumInEndOfVmFiles (getVmFiles fileList) name w
假设 getVmFiles
在我的 FileManipulation.dcl
文件中定义,并且在这个问题的上下文中 name
是 "myDir"
并且文件列表是 ["hello.vm","Wiki.vm"]
出于某种原因,即使我在屏幕上看到 "finished" 消息,文件也没有被修改。无论我给 fopen
什么样的整数,即使它的 FWriteText
或 FWriteData
它仍然什么都不做......即使我使用 fwritec
或 fwrites
字符没有任何反应。
我在这里缺少什么?非常感谢!
For some reason, even that I got "finished" message on the screen, the files aren't modified.
这是由于 lazy evaluation。 appendNumInEndOfVmFiles
中没有使用fclose
的结果,所以fclose
不求值。因此,fwritei
也不需要计算。您可以通过在 ok2
:
# (ok2,_) = fclose file w
| not ok2 = abort "fclose failed\n"
= appendNumInEndOfVmFiles xs dirname w
但是,执行此操作的典型方法是将函数重写为 return 和 *f
而不是 String
,这样这个唯一值就不会丢失。只要使用了结果,那么,fwritei
就被评估了。您可以使 *f
参数严格(即在前面添加 !
)。这将确保在进入函数之前对其进行评估,以便执行所有延迟文件关闭。
您的代码还有一些问题:
这里用了两次
w
,是不合法的,因为是严格类型。您应该在守卫中使用(ok2,w)
以继续相同的环境。# (ok2,_) = fclose file w = appendNumInEndOfVmFiles xs dirname w
[= 的重载问题52=]appendNumInEndOfVmFiles
需要类型上下文| FileSystem f
来解决fopen
和fclose
.
最后:
... even if its
FWriteText
orFWriteData
...
如你所知:不同之处在于第一个会以 ASCII 表示形式写入整数,而第二个会将其二进制写入 4 或 8 个字节(取决于系统的位宽)。