Input/Output Chapters 7 & 9
Output n Print produces output > (print 100) n It also returns the value it printed –that’s where the second 100 came from
Input n Read reads & returns a form –it does not get evaluated > (read) (no evaluation at all) (NO EVALUATION AT ALL) n No variable to read into, either –use (setf var-name (read)) for that
Evaluating Input n Eval evaluates a list as a function –works on atoms, too > (eval ‘(+ 2 2)) 4 > (eval (read)) (+ 2 2) 4
Prompted Input >(defun read-student-name (ID) (print ‘(please enter name for student id)) (print ID) (read)) > (read-student-name 1123) (PLEASE ENTER NAME FOR STUDENT ID) 1123FredFRED
Strings n For nicer output –and for interaction with the O/S n Double-quotes around characters –sequence of characters > “This is a string” “This is a string” n Case sensitive – double quotes remain
Print v. Format n Print prints strings with quotes n Format prints strings without quotes > (and (print “This string”) (format t “This string”)) “This string” This string NIL Output from Print (includes leading newline & trailing space) Output from Format
Format n Format returns NIL n 1 st argument says where to send output –t means send it to the console (monitor) n 2 nd argument is string to print –must be a string – others lead to error n String may have directives –to do some useful stuff
Format Directive n Format directive is command to format n Directive starts with a tilde (~) –followed by optional arguments –plus optional and : –followed by single character command n (format t “~%”) – output an end-of-line –(format t “~5%”) – output 5 end-of-lines
The A Directive n ~A (or ~a) makes format look for an argument to print –argument added to format call –one argument for each ~a in the string > (format t “Student #~a is ~a~%” 1234 “Fred”) Student #1234 is Fred NIL n Note: string argument printed w/o quotes
Exercise n Use format with directives to re-implement the read-student-name function with a better prompt. > (read-student-name 1123) Please enter the name for student #1123: Fred FRED
File I/O n For I/O with files use with-open-file –creates a “stream” for reading or writing –gets attached to a file –gives a name to the stream that can be used with read, print & format >(with-open-file (inFile “data.txt” :direction :input) (read inFile)) (FIRST ITEM FROM “data.txt”)
With-Open-File n Opens stream & closes it when done –gets closed even if there was an error n 1 st argument a list with: –name of the input stream (local variable) –name of the file to attach (string) –:direction argument (:input, :output, …) n 2 nd argument is executed with the file open
File I/O Functions n For read, add the file stream as an argument –(read inFile) n For print, ditto –(print 25 outFile) n For format, replace T with file stream –(format outFile “Writes to the file.”)
File I/O n Each with-open-file is independent –starts at beginning of file when reading –tries to create a new file for output n Can nest them to get multiple streams open at same time n Can pass streams to functions –use stream parameters just like stream variables
Exercise n Write a function that takes a list and a stream and prints each element of that list into that stream > (with-open-stream (s “123.txt” :direction :output) (print-to-stream ‘(one two three) s)) one two three 123.txt Hint: remember mapcar & lambda
File Errors n Reading from a file that doesn’t exist –with-open-file generates an error n Writing to a file that does exist –with-open-file generates an error –add :if-exists :append to the 1 st argument > (with-open-file (fin “out.txt” :direction :output :if-exists :append) …) or :if-exists :overwrite, if you prefer
End-of-File Error n Trying to reads past end-of-file is an error n Unless you tell READ not to –set (optional) second argument to NIL >(with-open-file (fin “empty.txt” :direction :input) (read fin NIL)) NIL n Read returns NIL when read past EOF
End-of-File Return Value n NIL returned when read past EOF n But what if NIL is in your file? –will think it’s EOF before it really is n Use third argument to specify a return value –use something that won’t be in the file > (read fin nil ‘EOF) EOF Read returns this value when it reaches the end of file
Reading to End-of-File n Need indefinite iteration –to specify when to stop n Do special form –(do ) >(with-open-file (fin “data.txt” :direction :input) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof))))
Do Special Form n Variable list, each one: –variable name, initial value, update value n Test-return –stop the loop when the test is true –value to return (evaluated after test succeeds) n Body –executed once per iteration
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof)))) n count initialized to –1 & term to NIL n term not eql EOF n term set to EOF (nothing in the file to read) n count updated to count + 1 = 0 n term eql EOF return count 0
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof)))) n count initialized to –1 & term to NIL n term not eql EOF n term set to EOF (nothing in the file to read) n count updated to count + 1 = 0 n term eql EOF return count 0
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof)))) n count initialized to –1 & term to NIL n term not eql EOF n term set to EOF (nothing in the file to read) n count updated to count + 1 = 0 n term eql EOF return count 0
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof)))) n count initialized to –1 & term to NIL n term not eql EOF n term set to EOF (nothing in the file to read) n count updated to count + 1 = 0 n term eql EOF return count 0
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL)) ((eql term ‘eof) count) (setf term (read fin nil ‘eof)))) n count initialized to –1 & term to NIL n term not eql EOF n term set to EOF (nothing in the file to read) n count updated to count + 1 = 0 n term eql EOF return count 0
Example (Empty File) (do ((count –1 (+ count 1)) (term NIL (read fin nil ‘eof))) (term NIL (read fin nil ‘eof))) ((eql term ‘eof) count)) n count initialized to –1 & term to NIL n term not eql EOF n count updated to count + 1 = 0, term updated to EOF (nothing in the file to read) n term eql EOF return count 0
Do vs. For (do ((i 10 (– i 1))) ((<= i 0) result) ) ) (do ((i 1 (+ i 1)) (j 1 (* j 2))) (j 1 (* j 2))) ((> i 10) result) ) ) for (i=10; i>0; i– –) <body>; return result; for (i=1, j=1; i <= 10; i++, j*=2) <body>; return result;
Read to EOF, Standard Form fread(fin, n); while (fin) { <process>; fread(fin, n); } (do ((n (read fin NIL) (read fin NIL))) ((not n) result) <process>) n Read initial value –update by reading another value n Same as for imperative
Exercise n Write a function that reads each element from the file “lists.txt” and prints the first element of each list into file “firsts.txt” –overwrite previous “firsts.txt”, if it exists (one two three) (a b c) (do re mi) one a do lists.txtfirsts.txt (lists-to-firsts)
Character Input n Read-char reads a single character n Read-line reads until the next end-of-line –returns a string n Both use same extra arguments as read > (list (read-char) (read-line)) This is my input (#\T “his is my input”)
Characters n Single characters printed with #\ in front –#\Y is the character capital Y –#\* is the character asterisk n Special characters have names –#\Space is the space character –#\Newline & #\Tab likewise –#\Asterisk = #\*
Character Equality n Characters are equal only if same case n Char-equal does case-insensitive compare > (equal #\A #\A) T > (equal #\a #\A) NIL > (char-equal #\a #\A) T
String Equality n Strings are equal only if same case n String-equal does case-insensitive compare > (equal “ABC” “ABC”) T > (equal “abc” “ABC”) NIL > (string-equal “abc” “ABC”) T
Substrings n Search looks for substring –returns position of substring (0 = 1 st position) –returns NIL if it’s not there –(search “abc” “abcdef”) => 0 –(search “cde” “abcdef”) => 2 –(search “fgh” “abcdef”) => NIL –(search “BC” “abcdef”) => NIL –(search “BC” “abcdef” :test #’char-equal) => 1
Converting to String n Search requires string arguments –won’t find a character in a string n Convert character to string using string (search (string #\d) “bad dog”) => 2 n String also works on atoms (string ‘fred) => “FRED” –doesn’t work on lists
Strings & Lists n Many list functions work on strings –(length “abc”) => 3 –(reverse “abcd”) => “dcba” –(elt “abcd” 1) => b n Nth works on lists, but not strings –(nth 1 ‘(a b c d)) => b –(nth 1 “abcd”) => ERROR
Exercise n Write a function that scans a text file & prints out the lines containing the string “his” (or “His”, or “HIS”, …) –the name of the text file is given –prefix each line printed with its line number Hello. I’m writing to tell you his story. This may take a while. 3: his story. 4: This may take a while. (scan-for-his “input.txt”) input.txt
Next Time n Midterm test n Next Tuesday –Repetition controls in LISP