右对齐文本 Lisp
Right Justified Text Lisp
我正在尝试让我的 lisp 代码输出右对齐的内容。我查阅了格式 (doc link) 的文档并尝试了以下
(format t "~10:<*~>")
问题是运行这段代码给了我这个:
* *
*
而不是给我这样的东西:
**
*
下面是整个函数,但我不认为它是导致任何问题的函数:
(defun triangle-print-neg (rows numStar)
(cond
((= rows 0) (return-from triangle-print-neg nil)) ;If rows = 0, force exit
((< numStar (abs rows)) (progn
(format t "~10:<*~>")
(triangle-print-neg rows (+ numStar 1)) ;Call function again but with numStar + 1
)); numStar < abs(rows) print("*")
(t (progn
(format t "~%")
(triangle-print-neg (+ rows 1) 0)
)) ; Else call triangle print neg with row+1, 0
)
)
谢谢
鉴于您的潜在问题,即打印三角形,大概是学习 Lisp 练习的一部分,并且您(我猜)对 Common Lisp 不是很熟悉,我建议 not 试图理解 format
字符串语言的细节,这很复杂并且与 Lisp 完全无关,除非它恰好嵌入在 CL 中,而是简单地编写一个函数来做使用简单的打印操作即可实现。
您需要的两个简单的打印操作是:
princ
打印没有任何修饰的东西,如换行符或引号;
terpri
打印换行符。
鉴于这两个操作,您可以编写一个过程 princ-n-padded
,它打印 n
个字符的副本,填充到给定的宽度,然后是换行符。您可以使用使宽度为负的肮脏技巧来指示右侧的填充。
下面是这样一个程序:
(defun print-n-padded (c n width &optional (to *standard-output*))
"Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified, if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
(if (>= width 0)
(dotimes (i width)
(princ (if (< i n) c #\Space) to))
(dotimes (i (- width))
(princ (if (< i (- (- width) n)) #\Space c) to)))
(terpri to))
现在
> (dotimes (i 10)
(print-n-padded #\* (+ i 1) -10))
*
**
***
****
*****
******
*******
********
*********
**********
nil
如您所见,这是简单的代码,没有繁琐难懂的 format
字符串。在现实生活中,您可能最终想以 non-trivial 的方式开始使用 format
,但通常更容易编写执行您想要的代码,其中您想要的东西相对简单,而不是而不是编写充满 line-noise 个字符串的代码。
如果您需要递归执行此操作,那么您也可以这样做:
(defun print-n-padded (c n width &optional (to *standard-output*))
"Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified, if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
(if (>= width 0)
(princ-ab c #\Space width (- width n) to)
(princ-ab #\Space c (- width) n to))
(terpri to))
(defun princ-ab (a b n m to)
"print (with PRINC) a total of N copies of A or B, printing N-M of A
followed by M of B, to TO. Do not print a newline"
(cond ((> n 0)
(princ (if (<= n m) b a) to)
(princ-ab a b (- n 1) m to))
((= n 0)
nil)
((< n 0)
(error "negative-creep"))))
(defun my-triangle (k)
(format t "~10@a~&" (make-string k :initial-element #\a))
(unless (zerop k)
(my-triangle (decf k))))
MY-TRIANGLE
CL-USER> (MY-TRIANGLE 5)
aaaaa
aaaa
aaa
aa
a
NIL
我使用 ~a
填充 10 和 left-align @
修饰符:https://lispcookbook.github.io/cl-cookbook/strings.html#justifying-on-the-left-
我正在尝试让我的 lisp 代码输出右对齐的内容。我查阅了格式 (doc link) 的文档并尝试了以下
(format t "~10:<*~>")
问题是运行这段代码给了我这个:
* * *
而不是给我这样的东西:
** *
下面是整个函数,但我不认为它是导致任何问题的函数:
(defun triangle-print-neg (rows numStar)
(cond
((= rows 0) (return-from triangle-print-neg nil)) ;If rows = 0, force exit
((< numStar (abs rows)) (progn
(format t "~10:<*~>")
(triangle-print-neg rows (+ numStar 1)) ;Call function again but with numStar + 1
)); numStar < abs(rows) print("*")
(t (progn
(format t "~%")
(triangle-print-neg (+ rows 1) 0)
)) ; Else call triangle print neg with row+1, 0
)
)
谢谢
鉴于您的潜在问题,即打印三角形,大概是学习 Lisp 练习的一部分,并且您(我猜)对 Common Lisp 不是很熟悉,我建议 not 试图理解 format
字符串语言的细节,这很复杂并且与 Lisp 完全无关,除非它恰好嵌入在 CL 中,而是简单地编写一个函数来做使用简单的打印操作即可实现。
您需要的两个简单的打印操作是:
princ
打印没有任何修饰的东西,如换行符或引号;terpri
打印换行符。
鉴于这两个操作,您可以编写一个过程 princ-n-padded
,它打印 n
个字符的副本,填充到给定的宽度,然后是换行符。您可以使用使宽度为负的肮脏技巧来指示右侧的填充。
下面是这样一个程序:
(defun print-n-padded (c n width &optional (to *standard-output*))
"Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified, if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
(if (>= width 0)
(dotimes (i width)
(princ (if (< i n) c #\Space) to))
(dotimes (i (- width))
(princ (if (< i (- (- width) n)) #\Space c) to)))
(terpri to))
现在
> (dotimes (i 10)
(print-n-padded #\* (+ i 1) -10))
*
**
***
****
*****
******
*******
********
*********
**********
nil
如您所见,这是简单的代码,没有繁琐难懂的 format
字符串。在现实生活中,您可能最终想以 non-trivial 的方式开始使用 format
,但通常更容易编写执行您想要的代码,其中您想要的东西相对简单,而不是而不是编写充满 line-noise 个字符串的代码。
如果您需要递归执行此操作,那么您也可以这样做:
(defun print-n-padded (c n width &optional (to *standard-output*))
"Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified, if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
(if (>= width 0)
(princ-ab c #\Space width (- width n) to)
(princ-ab #\Space c (- width) n to))
(terpri to))
(defun princ-ab (a b n m to)
"print (with PRINC) a total of N copies of A or B, printing N-M of A
followed by M of B, to TO. Do not print a newline"
(cond ((> n 0)
(princ (if (<= n m) b a) to)
(princ-ab a b (- n 1) m to))
((= n 0)
nil)
((< n 0)
(error "negative-creep"))))
(defun my-triangle (k)
(format t "~10@a~&" (make-string k :initial-element #\a))
(unless (zerop k)
(my-triangle (decf k))))
MY-TRIANGLE
CL-USER> (MY-TRIANGLE 5)
aaaaa
aaaa
aaa
aa
a
NIL
我使用 ~a
填充 10 和 left-align @
修饰符:https://lispcookbook.github.io/cl-cookbook/strings.html#justifying-on-the-left-