Common Lisp學習筆記(九)

9 Input/Output

9.2 string

string在lisp中用雙引號括起來,它的值也是本身自己,和數字同樣,string不是symbolscookie

stringp判斷是不是一個string函數

> "hello"
"hello"

> (stringp "hello")
t

9.3 format

format用來輸出到顯示器或者文件中,函數老是返回nil.輸出到顯示器的時候,第一個參數是t,第二個參數是stringatom

> (format t "hello")
hello
nil

string中如下幾個符號有特殊含義:lua

  • ~% : 輸出換行
  • ~& : 輸出換行,除非恰好在新的一行開始的位置。意思就是及時有幾個~&符號也只會輸出一個換行
  • ~S : 用後面的字符替換,如(format t "from ~S to ~S" 'guangzhou 'zhuhai) -> from guangzhou to zhuhai
  • ~A: 與~S相似,可是不使用escape characters,eg
    (defun test (x)
      (format t "~&with escape chars: ~S" x)
      (format t "~&without escape chars: ~A" x))
    
    > (test "hello")
    with escape chars: "hello"
    without escape chars: hello
    nil
    

ex 9.2spa

(defun draw-line (n)
  (cond ((equal n 1) (format t "*~&"))
        (t (format t "*") (draw-line (- n 1)))))

ex 9.3code

(defun draw-box (x y)
  (cond ((equal y 1) (draw-line x))
        (t (draw-line x) (draw-box x (- y 1)))))

ex 9.5orm

(defun print-board (b)
  (labels ((print-line (line) (format t " ~A | ~A | ~A ~%" (first line) (second line) (third line))))
  (let ((b1 (sublis '((x . "X")
                     (o . "O")
                     (nil . " ")) b)))
  (format t "~&")
  (print-line b1)
  (format t "-----------~%")
  (print-line (nthcdr 3 b1))
  (format t "-----------~%")
  (print-line (nthcdr 6 b1)))))

9.4 read

read函數從鍵盤讀取一個對象而後返回對象的值,對象前面不須要加',由於它不會被evaluated對象

(defun my-square ()
  (format t "enter a number:")
  (let ((x (read)))
    (format t "the number ~S squared is ~S.~%" x (* x x))))

ex 9.7get

(defun cookie-monster ()
  (format t "give me cookie!!!~%cookie?")
  (let ((response (read)))
    (cond ((equal response 'cookie) 
           (format t "~&thank you!...munch munch munch ...burp~%"))
          (t (format t "~&no want ~S....~%" response)
             (cookie-monster)))))

9.5 yes-or-no-p

(defun riddle ()
  (if (yes-or-no-p "do you seek zen enlightenment?")
      (format t "then do not ask for it!")
      (format t "you have found it.")))

> (riddle)
do you ...?yes
then do not ask for it!

yes-or-no-p函數輸出後面的string內容,而後要求用戶輸入yes或者no,表明函數返回t或者nilstring

9.6 with-open-file

(with-open-file (var pathname)
    body)

打開路徑下文件名的文件,並建立變量名var的stream object用來操做

eg,

(defun get-tree-data ()
  (with-open-file (stream "~/hello.dat")
    (let* ((tree-loc (read stream))
           (tree-table (read stream))
           (num-trees (read stream)))
     (format t "~&there are ~S trees on ~S." num-trees tree-loc)
     (format t "~&they are:   ~S." tree-table))))

> (get-tree-data)
there are 100 trees on "the north slope"
they are : ((45 redwood) (12 oak) (43 maple))
nil

read stream每次從文件中讀取一個lisp對象

9.7 writing files with with-open-file

format函數的第二個參數是t表明輸出到顯示器,改爲文件的stream object則輸出到文件中

咱們能夠輸入任意內容到文件中,內容能夠不是lisp的對象,好比不成對的小括號等,可是後面就不能使用read stream的形式來進行讀取

ex 9.10

(defun test (n)
  (format t "~%>>>")
  (space-over n)
  (format t "<<<"))

(defun space-over (n) 
  (cond ((< n 0) (format t "error"))
        ((zerop n) nil)
        (t (format t " ") (space-over (- n 1)))))

(defun plot-one-point (plotting-string y-val)
  (space-over y-val)
  (format t "~A~&" plotting-string))

(defun plot-points (plotting-string y-vals)
  (mapcar #'(lambda (b) (plot-one-point plotting-string b)) y-vals)) 

(defun generate (m n) 
  (cond ((= m n) (list m))
        ((< m n) (cons m (generate (+ 1 m) n)))))

9.8 parameters to format directives

~S輸出替換字符,~10S則能夠設置輸出寬度爲10個字符 ~D輸出十進制整數 ~F輸出浮點數,能夠設定總的位數和小數位數,如~7,5F輸出5位小數,總共佔7個字符

9.9 file EOF

當程序讀到文件的結尾時,會產生end-of-file error。給read增長兩個參數能夠不產生報錯,第一個是nil,表示不產生錯誤,第二個是eof indicator,表示讀到這個對象就表明結尾

(defun read-my-file ()
  (with-open-file (stream "~/hello.dat")
    (let ((contents (read-all-objects stream (list '$eof$))))
     (format t "~&read ~S objects from the file." (length contents))
     contents)))

(defun read-all-objects (stream eof-indicator)
  (let ((result (read stream nil eof-indicator)))
    (if (eq result eof-indicator) nil (cons result (read-all-objects stream eof-indicator)))))

例子中使用(list '\(eof\))做爲結尾標識,這是一個新建的cons,後面進行比較的時候用eq而不是equal是爲了對地址進行比較,確認就是結尾標識。

ex 9.11

(defun dot-prinl (x)
  (cond ((null x) (format t "nil"))
        ((atom x) (format t "~S" x))
        (t (format t "(") 
           (dot-prinl (car x)) 
           (format t " . ")
           (dot-prinl (cdr x))
           (format t ")"))))
相關文章
相關標籤/搜索