Pixel Graphics, Inc. - Litigation & Court Graphics
3423 Rivers Edge Trail
Houston, Texas 77339
Copyright 2008 - Pixel Graphics, Inc. All rights reserved.
AutoLisp Tutorial: File Handling - Reading Data from External Files
Welcome to my Autolisp tutorial on reading data from external files. Reading and writing external files can
seem daunting to anyone who hasn't done it much, but I've developed a method over the years that
makes life consistent and easy. Let's get right to it.

The first trick that I'd highly recommend is to always use comma-delimited files. The reason behind this is
that Microsoft Excel will automatically open this file type if the extension is CSV (e.g. datafile.csv) . The
translation is absolutely perfect.  You can enter your data in Excel and then save it as a CSV file and it will
format properly. I've experimented with other formats and this one wins hands down for ease of use and
ripping out some quick and dirty Autolisp code.
What is a Comma Delimited File?

Very simply, it is an ASCII file in which each line contains data values that are separated by commas. The
comma is called the delimiter.  Opening a comma delimited file in Notepad might look something like the
;=  Function  PARSE_NUMS (string)
;=    Arguments: string - Text string to be comma parsed
;=    Returns:   A list of the elements of the string converted to numbers
;=    Copyright Jeff Winship 2003. All rights reserved.
;=    www.pixelgraphicsinc.com
(defun parse_nums (st / a k lst)
(setq k 1)
(setq a "")
(setq lst nil)
(repeat (strlen st)
(if (= (substr st k 1) ",")
(setq lst (append lst (list (atof a))))
(setq a "")
(setq a (strcat a (substr st k 1)))
(setq k (+ k 1))
(setq lst (append lst (list (atof a))))
Width, Height
4, 10
2, 8
3, 5
6, 12
Notice that the string values don't have to have parentheses around the string values. Although it's not
required, I almost always add a line a the top like the "Width, Height" as a header that identifies to me
what each column of data represents. It's a really good habit to get into, trust me.

I also add a line at the end of the data file as shown that reads "EOF", indicating that you've reached the
end of the file. It makes the Autolisp coding a little easier.
Telling Autolisp What File You Want to Read

The first step is to tell Autolisp to open the file, also telling it that you want to read from the file, versus
writing to, or appending to the file.

The basic syntax for this is:

(setq f (open "SampleData.csv" "r"))

This statement literally reads "Open SampleData.csv for Reading and assign the file name to the variable
f ". We assign the filename to the variable f so that have a way to refer to it. For example, if we needed to
open a file to read and also a different file to write data out to, Autolisp will then have a way to identify
which file you're talking about. We might set up the file to write out to as follows:

(setq g (open "OutputData.csv" "w"))

In this example, we are reading from file f and writing data out to file g .

*Note: You'll need to specify a path name to the data file, and Autolisp is a little bizarre in the way that you
do it. Just remember to use single forward slashes like the following example when you specify the path
and filename and you won't have any problems.

(setq g (open "c:/test data/SampleData.csv" "r"))
How to Read the Data from the File

Now that we understand the two Autolisp functions (open) and (read-line), we're ready to start building the
code. First we need to read past the header line (it's no help to the program), then set up a loop that reads
line by line through the file. Assume we use SampleData.csv data file from above and the data represents
the width and height of a list of four rectangles you want to draw with the lower left corner at the origin. We
start by creating our new command, then opening the file for read, then setting up the loop as follows:
(defun c:rects ()
(setq f (open "c:/test/sampledata.csv" "r")) ;-Opens the file to read
(setq dataline (read-line f))                ;-Reads the header
(setq dataline (read-line f))                ;-Reads the 1st data line
(while (/= dataline "EOF")                   ;-Loop until the end of file

(setq dataline (read-line f))              ;-Read the next data line
(close f)                                    ;-Close the file
Reading a Line of Data from a File

The command we'll use to read the data from the file is with the read-line Autolisp function.  The basic
syntax is as follows:

(setq dataline (read-line f))

Every time it's called, the read-line function reads a single line of data one by one from the data file and
returns it (saves it) to our variable
dataline. Every time you call (use) the read-line function, it reads the
next line of data in the file. This line of code literally reads "Read the next line of data from the file
f and
save it to the variable
At this point we are reading the data from the file line by line.....but we've got a problem. How do we
separate the commas out of each line of data and make a list out of it?

Fortunately, I wrote an Autolisp function years ago that handles that automatically for you. You don't need
to understand the function code, just paste it into the program at the end of the file. Make sure it's not
inside the parentheses of the "rects" command code. To use the function, simply send it the dataline, and
it will return the data line in a list converted to floating point numbers.

Feel free to copy the code, just be sure to keep my copyright info in it and don't modify it without my
permission. I'd also appreciate it if you find this function useful, please include a link to my site on your web
Jeff Winship - Computer Graphics Consultant                                                                                                                                                    April 15, 2008
Autolisp Function Freeware: Comma Delimited File Parser - Courtesy Jeff Winship
Now that we've got a solution to the parsing problem, let's finish it up. The next task is to parse the line,
then draw the rectangles, and we're done. Here's the finished Autolisp code:
(defun c:rects ()
(setq f (open "c:/test/sampledata.csv" "r"))  ;-Open the data file
(setq dataline (read-line f))                 ;-Read the header line
(setq dataline (read-line f))                 ;-Read the 1st data line
(while (/= dataline "EOF")                    ;-Loop until end of file
(setq dataline (parse_nums dataline))       ;-Parse the data line
(command "_rectangle" (list 0 0)dataline)   ;-Draw the rectangle
(setq dataline (read-line f))               ;-Read the next data line
(close f)                                     ;-Close the file!!!
If you have any comments or questions regarding this technique or code, feel free to e-mail me at: