The Scheme Programming Language, Third Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

The Scheme Programming Language, Third Edition [Electronic resources] - نسخه متنی

Jean-Pierre Hbert, R. Kent Dybvig

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید





Section 9.4 requires a sequence of four calls to output routines to print a simple one-line message:


(write (tree-count node) p)
(write-char #\space p)
(display (tree-word node) p)
(newline p)

The formatted output facility defined in this section allows these four calls to be replaced by the single call to fprintf below.


(fprintf p "~s ~a~%" (tree-count node) (tree-word node))

fprintf expects a port argument, a control string, and an indefinite number of additional arguments that are inserted into the output as specified by the control string. In the example, the value of (tree-count node) is written first, in place of ~s. This is followed by a space and the displayed value of (tree-word node), in place of ~a. The ~% is replaced in the output with a newline.

The procedure printf, also defined in this section, is like fprintf except that no port argument is expected and output is sent to the current output port.

~s, ~a, and ~% are format directives; ~s causes the first unused argument after the control string to be printed to the output via write, ~a causes the first unused argument to be printed via display, and ~% simply causes a newline character to be printed. The simple implementation of fprintf below recognizes only one other format directive, ~~, which inserts a tilde into the output. For example,


(printf "The string ~s displays as ~~.~%" "~")

prints


The string "~" displays as ~.
---------------------------------------------------------------------------
(let ()
;; dofmt does all of the work. It loops through the control string
;;recognizing format directives and printing all other characters
;;without interpretation. A tilde at the end of a control string is
;;treated as an ordinary character. No checks are made for proper
;;inputs. Directives may be given in either lower or upper case.
(define dofmt
(lambda (p cntl args)
(let ((nmax (- (string-length cntl) 1)))
(let loop ((n 0) (a args))
(if (<= n nmax)
(let ((c (string-ref cntl n)))
(if (and (char=? c #\~) (< n nmax))
(case (string-ref cntl (+ n 1))
((#\a #\A)
(display (car a) p)
(loop (+ n 2) (cdr a)))
((#\s #\S)
(write (car a) p)
(loop (+ n 2) (cdr a)))
((#\%)
(newline p) (loop (+ n 2) a))
((#\~)
(write-char #\~ p)
(loop (+ n 2) a))
(else
(write-char c p)
(loop (+ n 1) a)))
(begin
(write-char c p)
(loop (+ n 1) a)))))))))
;; printf and fprintf differ only in that fprintf passes its
;;port argument to dofmt while printf passes the current output
;;port.
(set! printf
(lambda (control . args)
(dofmt (current-output-port) control args)))
(set! fprintf
(lambda (p control . args)
(dofmt p control args))))

Exercise 9.6.1.






Using the optional radix argument to number->string, augment printf and fprintf with support for the following new format directives:



~b or ~B: print the next unused argument, which must be a number, in binary;



~o or ~O: print the next unused argument, which must be a number, in octal; and



~x or ~X: print the next unused argument, which must be a number, in hexadecimal.



For example:


(printf "#x~x #o~o #b~b~%" 16 8 2)

would print


#x10 #o10 #b10











Exercise 9.6.2.






Add an "indirect" format directive, ~@, that treats the next unused argument, which must be a string, as if it were spliced into the current format string. For example:


(printf "--- ~@ ---" "> ~s <" '(a b c))

would print


---> (a b c) <---











Exercise 9.6.3.






Implement format, a version of fprintf that places its output into a string instead of writing to a port. Make use of object->string from Exercise 9.5.2 to support the ~s and ~a directives.


(let ((x 3) (y 4))
(format "~s + ~s = ~s" x y (+ x y))) ⇒ "3 + 4 = 7"











Exercise 9.6.4.






Modify format, fprintf, and printf to allow a field size to be specified after the tilde in the ~a and ~s format directives. For example, the directive ~10s would cause the next unused argument to be inserted into the output left- justified in a field of size 10. If the object requires more spaces than the amount specified, allow it to extend beyond the field.


(let ((x 'abc) (y '(def)))
(format "(cons '~5s '~5s) = ~5s"
x y (cons x y))) ⇒ "(cons 'abc '(def)) = (abc def)"

[Hint: Use format recursively.]











/ 98