Common Lisp 中的字符集

Charsets in Common Lisp

我一直在研究一个通用的 lisp 程序,该程序解析两个 XML 文件并以自定义方式组合它们以生成第三个 XML。不幸的是,lisp 使用 CP1252 字符集,而我的 XML 文件使用 UTF-8 并包含一些不能在 CP1252 中使用的日语字符。

我一直在尝试通过添加

让 clisp 使用 UTF-8
:external-format 'charset:UTF-8

加载(如建议)和read-line(因为为什么不)都起作用,但clisp仍然抛出此错误:

READ-LINE: Invalid byte #x81 in CHARSET:CP1252 conversion

有没有办法用我的代码做我想做的事?我对 lisp 还是很陌生。

全读函数代码:

(defun readXML (stream libSize)
    (defparameter lib nil)
    (defparameter x 1)
    (loop
        (defparameter lib (cons (read-line stream :external-format 'charset:UTF-8) lib))
        (defparameter x (+ x 1))
        (when (> x libSize) (return lib))))

错误

read-line

此函数接受:external-format参数。

它确实接受了几个可选参数,但它们无关 带编码。

defparameter

这是一个 "top-level" 运算符,它创建一个全局 dynamic variable从不 在函数中使用它。 使用 let there instead - it binds variables lexicallyloop(见下文)也绑定变量。

正确的代码

(defun read-lines (file-name max-lines)
  "Open the file and read it line-by-line, at most `max-lines'."
  (with-open-file (stream file-name :external-format charset:utf-8)
    (loop :for line = (read-line stream nil nil)
      :for line-number :upfrom 0
      :while (and line (< line-number max-lines))
      :collect line)))

或者,稍微简单一点(如@jkiiski 所建议):

(defun read-lines (file-name max-lines)
  "Open the file and read it line-by-line, at most `max-lines'."
  (with-open-file (stream file-name :external-format charset:utf-8)
    (loop :for line = (read-line stream nil nil)
      :repeat max-lines
      :while line
      :collect line)))

解释

  • with-open-file 打开 文件,将 stream 绑定到结果并确保流是 退出时关闭。

  • loop是一个很高级的 迭代设施。它将 line 绑定到每个连续的行,计数 他们使用 line-number,并将行收集到 return 值中:

PS。请点击答案中的所有链接。 他们详细解释了每个运算符。