我想通过格式化的方式输出一个字符多次。这可能吗?是否有人能够填写_?_
,以便示例代码可以正常工作?
(let ((n 3))
(format nil "_?_" _?_ #\* _?_ ))
应该返回
=> "***"
我想通过格式化的方式输出一个字符多次。这可能吗?是否有人能够填写_?_
,以便示例代码可以正常工作?
(let ((n 3))
(format nil "_?_" _?_ #\* _?_ ))
应该返回
=> "***"
看到这么多解决方案真是太好了:~A, ~<, 和 ~{。
使用 ~@{ 迭代结构可以提供一个简洁的解决方案:
(format nil "~v@{~A~:*~}" 3 #\*)
(format nil "~a~:*~a~:*~a~:*" #\*)
"***"
(format nil "~v{~a~:*~}" 3 '(#\*))
这是一种实现方法。不要被format
指令中的星号所困扰,它们是控制符号,而不是要打印的字符。
然而,从效率角度考虑,下面的方法更好:
(make-string 3 :initial-element #\*)
~A
指令,您可以以您建议的形式准确地获得此内容,即,(let ((n 3))
(format nil "_?_" _?_ #\* _?_ ))
有三个格式参数。但是,如果使用~<
,您实际上只需使用两个格式参数即可完成此操作。如果您不需要在format
已经生成的某些其他字符串中使用此字符串,则还可以使用make-string
创建字符串。
您可以打印字符并指定最小宽度和相同的字符作为填充字符。例如,使用~v,,,vA
和两个参数,您可以确保打印一些字符,并指定填充字符是什么。
CL-USER> (let ((n 3))
(format nil "~v,,,vA"
n ; number of characters that must be printed
#\* ; character to use as padding
#\*)) ; character to print with ~A
"***"
CL-USER> (let ((n 3))
(format nil "~v,,,vA" n #\* #\*))
"***"
CL-USER> (let ((n 10))
(format nil "~v,,,vA" n #\* #\*))
"**********"
这里使用了完整形式的~A
:
~mincol,colinc,minpad,padcharA是
~A
的完整形式,它允许控制填充。字符串在右侧(如果使用@修饰符,则在左侧)至少用minpad个padchar进行填充;然后每次插入colinc个字符,直到总宽度至少为mincol。默认值为mincol和minpad为0,colinc为1,padchar为空格字符。
以及v
:
CL-USER> (let ((n 3))
(format nil "~v,,,v<~>"
n ; width
#\*)) ; padding character
"***"
CL-USER> (let ((n 5))
(format nil "~v,,,v<~>" n #\*))
"*****"
当然,除非你需要在已经格式化的其他字符串内使用这个特殊字符串,否则应该按照wvxvw的建议,只需使用make-string
:
(make-string 3 :initial-element #\*)
format
非常灵活,正如本答案和其他答案所指出的那样,有许多方法可以实现这一点。我尝试坚持使用一遍完成而不进行显式迭代的方法,但是像Lars Brinkhoff和wvxvw所指出的那样,也可以使用format
迭代来完成。
像Lars的答案一样,但我们使用带有~C
的字符来书写,而不是使用带有~A
的打印机:
(format nil "~v@{~C~:*~}" 3 #\*)
write-char
的方法编写字符比打印Lisp对象简单。打印机需要观察许多上下文并找到正确的打印方式。而WRITE-CHAR
等方法只需将单个字符写入流中。
format
不会将输出发送到流中,但会创建一个包含输出的字符串。 - Rainer Joswigloop
和Unix/Linux中的find
也是嵌入式语言。如果你熟练掌握它们,那么非常方便,但它们与嵌入它们的语言完全不同。 - Drew