我不认为这可以很容易地format
的内置控制字符来完成,但你可以通过自己的函数吧:
(defun my-f (stream arg colon at &rest args)
(declare (ignore colon at))
(destructuring-bind (width digits &optional (pad #\Space)) args
(let* ((string (format nil "~v,vf" width digits arg))
(non-zero (position #\0 string :test #'char/= :from-end t))
(dot (position #\. string :test #'char= :from-end t))
(zeroes (- (length string) non-zero (if (= non-zero dot) 2 1)))
(string (nsubstitute pad #\0 string :from-end t :count zeroes)))
(write-string string stream))))
可以使用这样的:
CL-USER> (format t "~{|~16,5/my-f/|~%~}" '(798573.467 434.543543 2.435 34443.5 10))
| 798573.44 |
| 434.54355|
| 2.435 |
| 34443.5 |
| 10.0 |
NIL
填充字符默认为#\Space
,并且可以作为第三个参数是这样的:"~16,5,' /my-f/"
。
另一个实现使用loop
:
(defun my-f (stream arg colon at &rest args)
(declare (ignore colon at))
(loop with string = (format nil "~v,vf" (car args) (cadr args) arg)
and seen-non-zero = nil
for i from (1- (length string)) downto 0
as char = (char string i)
if (char/= char #\0) do (setq seen-non-zero t)
collect (if (and (not seen-non-zero)
(char= char #\0)
(not (char= #\. (char string (1- i)))))
(or (caddr args) #\Space)
char) into chars
finally (write-string (nreverse (coerce chars 'string)) stream)))
(免责声明:也许我忽略了一些的format
的文档更容易。)
我认为“优雅”胜出的幌子下,这是可以做到完全可以在'格式'框架内通过添加一个函数而不必扔掉整个套件。 – 2011-06-15 20:45:16
请问,我的意思是我执行'my-f',这可能会做得更好。例如,它可能不应该从'1.0'中删除'0'。当然,格式非常灵活! – danlei 2011-06-15 20:49:22
Somthing很奇怪,为什么798573.467显示为798573.44? (这种情况也是以普通格式发生的)@danlei – mmj 2011-06-17 07:09:09