string
在lisp中用雙引號括起來,它的值也是本身自己,和數字同樣,string不是symbolscookie
stringp
判斷是不是一個string函數
> "hello" "hello" > (stringp "hello") t
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)))))
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)))))
(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
(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對象
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)))))
~S
輸出替換字符,~10S
則能夠設置輸出寬度爲10個字符 ~D
輸出十進制整數 ~F
輸出浮點數,能夠設定總的位數和小數位數,如~7,5F
輸出5位小數,總共佔7個字符
當程序讀到文件的結尾時,會產生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 ")"))))