常见的 lisp:如何抑制换行符或 "soft return"
common lisp: how to suppress newline or "soft return"
这个代码
(defun arabic_to_roman (filename)
(let ((arab_roman_dp '())
(arab nil)
(roman nil))
(with-open-file (in filename
:direction :input
:if-does-not-exist nil)
(when in
(loop for line = (read-line in nil)
while line do
(setq arab (subseq line 0 (search "=" line)))
(setq roman (subseq line (1+ (search "=" line)) (length line)))
(setf arab_roman_dp (acons arab roman arab_roman_dp))
;(format t "~S ~S~%" arab roman)
)))
(with-open-file (stream #p"ar_out.txt"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create )
(write arab_roman_dp :stream stream :escape nil :readably nil))
'done!))
似乎效果不错。它需要一个包含这样条目的文件
1=I
2=II
...
并构建一大堆点对。但是,当我查看输出文件时,似乎插入了软 returns 或换行符。
((4999 . MMMMCMXCIX) (4998 . MMMMCMXCVIII) (4997 . MMMMCMXCVII)
(4996 . MMMMCMXCVI) (4995 . MMMMCMXCV) (4994 . MMMMCMXCIV)
(4993 . MMMMCMXCIII) (4992 . MMMMCMXCII) (4991 . MMMMCMXCI) (4990 . MMMMCMXC)
...
我希望输出看起来更像是一条连续的线:
((4999 . MMMMCMXCIX) (4998 . MMMMCMXCVIII) (4997 . MMMMCMXCVII) (4996 . MMMCMXCVI) (4995 . MMMMCMXCV) (4994 . MMMMCMXCIV) (4993 . MMMMCMXCIII) (4992 . MMMMCMXCII) (4991 . MMMMCMXCI) (4990 . MMMMCMXC) ...
我的代码确实以某种方式插入换行符吗?我使用了 princ
的 write
版本,据说可以抑制换行。后来我想把这个文件作为一个大列表读回程序,所以我不想要换行问题。
看起来漂亮打印机正在被调用(默认是依赖于实现的),以缩进和人类可读的行长打印它。使用 :pretty nil
禁用此功能。
(write arab_roman_dp :stream stream :escape nil :readably nil :pretty nil)
更好的写法:
- 使用函数创建可以组合的代码块
- 更少的副作用和更少的变量
- 无需测试
in
- 易于理解的控制流程
示例:
(defun arabic_to_roman (filename)
(flet ((read-it ()
(with-open-file (in filename
:direction :input
:if-does-not-exist nil)
(loop for line = (read-line in nil)
for pos = (position #\= line)
while line collect (cons (subseq line 0 pos)
(subseq line (1+ pos))))))
(write-it (list)
(with-open-file (stream #p"ar_out.txt"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create)
(write list :stream stream :escape nil :readably nil :pretty nil))))
(write-it (read-it))
'done-read-write))
这个代码
(defun arabic_to_roman (filename)
(let ((arab_roman_dp '())
(arab nil)
(roman nil))
(with-open-file (in filename
:direction :input
:if-does-not-exist nil)
(when in
(loop for line = (read-line in nil)
while line do
(setq arab (subseq line 0 (search "=" line)))
(setq roman (subseq line (1+ (search "=" line)) (length line)))
(setf arab_roman_dp (acons arab roman arab_roman_dp))
;(format t "~S ~S~%" arab roman)
)))
(with-open-file (stream #p"ar_out.txt"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create )
(write arab_roman_dp :stream stream :escape nil :readably nil))
'done!))
似乎效果不错。它需要一个包含这样条目的文件
1=I
2=II
...
并构建一大堆点对。但是,当我查看输出文件时,似乎插入了软 returns 或换行符。
((4999 . MMMMCMXCIX) (4998 . MMMMCMXCVIII) (4997 . MMMMCMXCVII)
(4996 . MMMMCMXCVI) (4995 . MMMMCMXCV) (4994 . MMMMCMXCIV)
(4993 . MMMMCMXCIII) (4992 . MMMMCMXCII) (4991 . MMMMCMXCI) (4990 . MMMMCMXC)
...
我希望输出看起来更像是一条连续的线:
((4999 . MMMMCMXCIX) (4998 . MMMMCMXCVIII) (4997 . MMMMCMXCVII) (4996 . MMMCMXCVI) (4995 . MMMMCMXCV) (4994 . MMMMCMXCIV) (4993 . MMMMCMXCIII) (4992 . MMMMCMXCII) (4991 . MMMMCMXCI) (4990 . MMMMCMXC) ...
我的代码确实以某种方式插入换行符吗?我使用了 princ
的 write
版本,据说可以抑制换行。后来我想把这个文件作为一个大列表读回程序,所以我不想要换行问题。
看起来漂亮打印机正在被调用(默认是依赖于实现的),以缩进和人类可读的行长打印它。使用 :pretty nil
禁用此功能。
(write arab_roman_dp :stream stream :escape nil :readably nil :pretty nil)
更好的写法:
- 使用函数创建可以组合的代码块
- 更少的副作用和更少的变量
- 无需测试
in
- 易于理解的控制流程
示例:
(defun arabic_to_roman (filename)
(flet ((read-it ()
(with-open-file (in filename
:direction :input
:if-does-not-exist nil)
(loop for line = (read-line in nil)
for pos = (position #\= line)
while line collect (cons (subseq line 0 pos)
(subseq line (1+ pos))))))
(write-it (list)
(with-open-file (stream #p"ar_out.txt"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create)
(write list :stream stream :escape nil :readably nil :pretty nil))))
(write-it (read-it))
'done-read-write))