📄 printf.scm
字号:
((8) "0") ((16) "0x") (else ""))) (else "")))) (pad pre (if (< (string-length s) precision) (make-string (- precision (string-length s)) #\0) "") s)))) (define (float-convert num fc) (define (f digs exp strip-0s) (let ((digs (stdio:round-string digs (+ exp precision) (and strip-0s exp)))) (cond ((>= exp 0) (let* ((i0 (cond ((zero? exp) 0) ((char=? #\0 (string-ref digs 0)) 1) (else 0))) (i1 (max 1 (+ 1 exp))) (idigs (substring digs i0 i1)) (fdigs (substring digs i1 (string-length digs)))) (cons idigs (if (and (string=? fdigs "") (not alternate-form)) '() (list "." fdigs))))) ((zero? precision) (list (if alternate-form "0." "0"))) ((and strip-0s (string=? digs "") (list "0"))) (else (list "0." (make-string (min precision (- -1 exp)) #\0) digs))))) (define (e digs exp strip-0s) (let* ((digs (stdio:round-string digs (+ 1 precision) (and strip-0s 0))) (istrt (if (char=? #\0 (string-ref digs 0)) 1 0)) (fdigs (substring digs (+ 1 istrt) (string-length digs))) (exp (if (zero? istrt) exp (- exp 1)))) (list (substring digs istrt (+ 1 istrt)) (if (and (string=? fdigs "") (not alternate-form)) "" ".") fdigs (if (char-upper-case? fc) "E" "e") (if (negative? exp) "-" "+") (if (< -10 exp 10) "0" "") (number->string (abs exp))))) (define (g digs exp) (let ((strip-0s (not alternate-form))) (set! alternate-form #f) (cond ((<= (- 1 precision) exp precision) (set! precision (- precision exp)) (f digs exp strip-0s)) (else (set! precision (- precision 1)) (e digs exp strip-0s))))) (define (k digs exp sep) (let* ((units '#("y" "z" "a" "f" "p" "n" "u" "m" "" "k" "M" "G" "T" "P" "E" "Z" "Y")) (base 8) ;index of "" (uind (let ((i (if (negative? exp) (quotient (- exp 3) 3) (quotient (- exp 1) 3)))) (and (< -1 (+ i base) (vector-length units)) i)))) (cond (uind (set! exp (- exp (* 3 uind))) (set! precision (max 0 (- precision exp))) (append (f digs exp #f) (list sep (vector-ref units (+ uind base))))) (else (g digs exp))))) (cond ((negative? precision) (set! precision 6)) ((and (zero? precision) (char-ci=? fc #\g)) (set! precision 1))) (let* ((str (cond ((number? num) (number->string (exact->inexact num))) ((string? num) num) ((symbol? num) (symbol->string num)) (else "???")))) (define (format-real signed? sgn digs exp . rest) (if (null? rest) (cons (if (char=? #\- sgn) "-" (if signed? "+" (if blank " " ""))) (case fc ((#\e #\E) (e digs exp #f)) ((#\f #\F) (f digs exp #f)) ((#\g #\G) (g digs exp)) ((#\k) (k digs exp "")) ((#\K) (k digs exp " ")))) (append (format-real signed? sgn digs exp) (apply format-real #t rest) '("i")))) (or (stdio:parse-float str (lambda (sgn digs expon . imag) (apply pad (apply format-real signed sgn digs expon imag)))) (pad "???")))) (do () ((case fc ((#\-) (set! left-adjust #t) #f) ((#\+) (set! signed #t) #f) ((#\ ) (set! blank #t) #f) ((#\#) (set! alternate-form #t) #f) ((#\0) (set! leading-0s #t) #f) (else #t))) (must-advance)) (cond (left-adjust (set! leading-0s #f))) (cond (signed (set! blank #f))) (set! width (read-format-number)) (cond ((negative? width) (set! left-adjust #t) (set! width (- width)))) (cond ((eqv? #\. fc) (must-advance) (set! precision (read-format-number)))) (case fc ;Ignore these specifiers ((#\l #\L #\h) (set! type-modifier fc) (must-advance))) ;;At this point fc completely determines the format to use. (if (null? args) (if (memv (char-downcase fc) '(#\c #\s #\a #\d #\i #\u #\o #\x #\b #\f #\e #\g #\k)) (wna))) (case fc ;; only - is allowed between % and c ((#\c #\C) ; C is enhancement (and (out (string (car args))) (loop (cdr args)))) ;; only - flag, no type-modifiers ((#\s #\S) ; S is enhancement (let ((s (cond ((symbol? (car args)) (symbol->string (car args))) ((not (car args)) "(NULL)") (else (car args))))) (cond ((not (or (negative? precision) (>= precision (string-length s)))) (set! s (substring s 0 precision)))) (and (out* (cond ((<= width (string-length s)) s) (left-adjust (list s (make-string (- width (string-length s)) #\ ))) (else (list (make-string (- width (string-length s)) (if leading-0s #\0 #\ )) s)))) (loop (cdr args))))) ;; SLIB extension ((#\a #\A) ;#\a #\A are pretty-print (let ((os "") (pr precision)) (generic-write (car args) (not alternate-form) #f (cond ((and left-adjust (negative? pr)) (set! pr 0) (lambda (s) (set! pr (+ pr (string-length s))) (out s))) (left-adjust (lambda (s) (define sl (- pr (string-length s))) (set! pr (cond ((negative? sl) (out (substring s 0 pr)) 0) (else (out s) sl))) (positive? sl))) ((negative? pr) (set! pr width) (lambda (s) (set! pr (- pr (string-length s))) (cond ((not os) (out s)) ((negative? pr) (out os) (set! os #f) (out s)) (else (set! os (string-append os s)))) #t)) (else (lambda (s) (define sl (- pr (string-length s))) (cond ((negative? sl) (set! os (string-append os (substring s 0 pr)))) (else (set! os (string-append os s)))) (set! pr sl) (positive? sl))))) (cond ((and left-adjust (negative? precision)) (cond ((> width pr) (out (make-string (- width pr) #\ ))))) (left-adjust (cond ((> width (- precision pr)) (out (make-string (- width (- precision pr)) #\ ))))) ((not os)) ((<= width (string-length os)) (out os)) (else (and (out (make-string (- width (string-length os)) #\ )) (out os))))) (loop (cdr args))) ((#\d #\D #\i #\I #\u #\U) (and (out* (integer-convert (car args) 10 #f)) (loop (cdr args)))) ((#\o #\O) (and (out* (integer-convert (car args) 8 #f)) (loop (cdr args)))) ((#\x) (and (out* (integer-convert (car args) 16 (if stdio:hex-upper-case? string-downcase #f))) (loop (cdr args)))) ((#\X) (and (out* (integer-convert (car args) 16 (if stdio:hex-upper-case? #f string-upcase))) (loop (cdr args)))) ((#\b #\B) (and (out* (integer-convert (car args) 2 #f)) (loop (cdr args)))) ((#\%) (and (out #\%) (loop args))) ((#\f #\F #\e #\E #\g #\G #\k #\K) (and (out* (float-convert (car args) fc)) (loop (cdr args)))) (else (cond ((end-of-format?) (incomplete)) (else (and (out #\%) (out fc) (out #\?) (loop args)))))))) (else (and (out fc) (loop args)))))))))(define (fprintf port format . args) (let ((cnt 0)) (apply stdio:iprintf (lambda (x) (cond ((string? x) (set! cnt (+ (string-length x) cnt)) (display x port) #t) (else (set! cnt (+ 1 cnt)) (display x port) #t))) format args) cnt))(define (printf format . args) (apply fprintf (current-output-port) format args))(define (sprintf str format . args) (let* ((cnt 0) (s (cond ((string? str) str) ((number? str) (make-string str)) ((not str) (make-string 100)) (else (error 'sprintf "first argument not understood" str)))) (end (string-length s))) (apply stdio:iprintf (lambda (x) (cond ((string? x) (if (or str (>= (- end cnt) (string-length x))) (do ((lend (min (string-length x) (- end cnt))) (i 0 (+ i 1))) ((>= i lend)) (string-set! s cnt (string-ref x i)) (set! cnt (+ cnt 1))) (let () (set! s (string-append (substring s 0 cnt) x)) (set! cnt (string-length s)) (set! end cnt)))) ((and str (>= cnt end))) (else (cond ((and (not str) (>= cnt end)) (set! s (string-append s (make-string 100))) (set! end (string-length s)))) (string-set! s cnt (if (char? x) x #\?)) (set! cnt (+ cnt 1)))) (not (and str (>= cnt end)))) format args) (cond ((string? str) cnt) ((eqv? end cnt) s) (else (substring s 0 cnt)))));;(do ((i 0 (+ 1 i))) ((> i 50)) (printf "%s\n" (sprintf i "%#-13a:%#13a:%-13.8a:" "123456789" "123456789" "123456789")))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -