如何解决如何将数组转换为cstring? 错误转换
我找到了 (here) 一个使用 Nim 计算文件 MD5 的程序的来源。 此程序不再编译 (nim 1.4),因为 array 到 cstring 之间的隐式转换已被禁用。
如何解决这个问题?
import md5
import os
proc calculateMD5Incremental(filename: string) : string =
const blockSize: int = 8192
var
c: MD5Context
d: MD5Digest
f: File
bytesRead: int = 0
buffer: array[blockSize,char]
byteTotal: int = 0
#read chunk of file,calling update until all bytes have been read
try:
f = open(filename)
md5Init(c)
bytesRead = f.readBuffer(buffer.addr,blockSize)
while bytesRead > 0:
byteTotal += bytesRead
md5Update(c,buffer,bytesRead) # <--- HERE buffer should be cstring
bytesRead = f.readBuffer(buffer.addr,blockSize)
md5Final(c,d)
except IOError:
echo("File not found.")
finally:
if f != nil:
close(f)
result = $d
if paramCount() > 0:
let arguments = commandLineParams()
echo("MD5: ",calculateMD5Incremental(arguments[0]))
else:
echo("Must pass filename.")
quit(-1)
注意:我对一般问题更感兴趣,而不是 MD5,这是手头的例子。
解决方法
在您的回答中,您使用 $
将数组转换为字符串。这虽然不返回 "ciao"
而是 "['c','i','a','o']"
。不确定您是否需要,但正确的转换方法如下:
const blockSize: int = 4
var
c: cstring
buffer: array[blockSize,char]
buffer = ['c','o']
c = cast[cstring](create(char,blockSize + 1))
moveMem(c[0].addr,buffer[0].addr,blockSize)
assert c == "ciao"
请注意,这是最佳的不安全解决方案。如果你想安全但慢一点,你可以使用这个代码:
const blockSize: int = 4
var
c: cstring
buffer: array[blockSize,char]
temp: string
buffer = ['c','o']
temp.setLen(blockSize)
for i in 0..<blockSize:
temp[i] = buffer[i]
c = temp
assert c == "ciao"
,
UPDATE 在这种情况下,这是完全错误的。正如接受的答案中指出的那样, $array 将以“屏幕友好”的方式呈现它。
正确的实现
md5(fromFile)的工作流程:
proc calculateMD5Incremental(filename: string) : string =
const blockSize: int = 8192
var
c: MD5Context
d: MD5Digest
f: File
s: cstring
bytesRead: int = 0
buffer: array[blockSize,char]
byteTotal: int = 0
#read chunk of file,calling update until all bytes have been read
try:
f = open(filename)
md5Init(c)
bytesRead = f.readBuffer(buffer.addr,blockSize)
while bytesRead > 0:
byteTotal += bytesRead
s = cast[cstring](create(char,blockSize + 1))
moveMem(s[0].addr,blockSize)
md5Update(c,s,bytesRead)
bytesRead = f.readBuffer(buffer.addr,blockSize)
md5Final(c,d)
except IOError:
stderr.writeLine("ERROR: File not found: ",filename)
finally:
if f != nil:
close(f)
result = $d
错误转换
~我发现可以接受常规字符串,因此 $buffer
会将数组转换为有效字符串:~
const blockSize: int = 4
var
c: cstring
buffer: array[blockSize,char]
buffer = ['c','o']
c = $buffer
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。