AutoCAD

AutoLISP Lesson #10 - INPUT AND OUTPUT
The most important part of any program, other than the internal calculations that occur, will be the input / output section. These are the parts of your program that deal with getting Information from the user and storing or retrieving data from a storage area. The Dialog Control Language (DCL) will not be covered in this text, due to the expansive nature of the subject.

The user interface
The user interface of your program is the most important part of your program as far as the user is concerned. If the program cannot easily be called and used, it will not be used. A program that is not used is worthless, and you have wasted your time and the company's money by writing it.
Each program you write will need to be evaluated to see what the user interface requirements are going to be. It is tempting to write major programs using DCL (Dialog Control Language) for every program you do, but that is generally getting carried away with things. The greatest benefit to be had from customizing AutoCAD is probably in the smaller tasks which, when selected from the menu, and with a few prompts, will deal with the interface quite nicely. Don’t get too exited about gathering a lot of your programs together into one program, as this could complicate your program to the point where no one will use it.
There are many predefined AutoLISP functions for dealing with the user interface, such that a flexible interface can be built without too much trouble. The GETX family of functions are the functions which ask the user for a large number of data types. The INITGET function may be used to set up the input system for some type checking and error trapping.

Using INITGET
INITGET is used to set up the input system for use with the GETX family of functions. You can combine several integers to set the GETX functions up to only allow certain types of input. 

(initget (+ 1 2))

This shows how the command should be used to set up the system. INITGET is called with several integers passed as the argument. The addition of these integers tells INITGET what values to allow the GETX family of functions to accept. As in the example, INITGET was passed a 1 and a 2, the (1) one tells INITGET to not accept nil input, the (2) two tells INIITGET to not accept a 0 as input for a number.

Using the GETX functions
With the GETX functions a variety of data types may be input into the system. The included data types are real numbers (floating point), integer numbers, strings, points, distances and angles. There is also a GETX function for defining a rectangle (window) and one for allowing the entry of keywords as input when getting a string.
A real number is a decimal or floating point number. The function for getting a real number is GETREAL. The INITGET function may be used with this function to limit the input to non-nil, non-0, positive numbers.
An integer is a whole number. The function for getting an integer is GETINT. The INITGET function may be used with this function to limit the user input to non-nil, non-0, positive numbers.
Using the GETSTRING function can retrieve a string. The INITGET function has no effect on this function. The GETKWORD function may be used with this function to limit the user input to certain keywords as passed to the GETKWORD function.
Using the GETPOINT function can retrieve a point. The INITGET function may be used with this function to limit the user input to non-nil values. It may also allow input of a point beyond the current limits setting. You can also turn the rubber band line from the first point to the second point into a dashed line instead of a solid line.
Using the GETDIST function can retrieve a distance. The INITGET function may be used with this function to limit the user input to this function to non-nil, non-0, non-negative and 2D distance only. You may also use INITGET to change the rubber band line from the first point to the second point to a dashed line instead of the normal solid line.
Using the GETANGLE function or the GETORIENT function can retrieve an angle. The GETANGLE function returns all angles in positive radians as measured from the horizontal axis. The GETANGLE function works according to how the units are set. If the units setting has the 0 degrees heading to the north the angle returned by GETANGLE will be relative to that setting. GETORIENT ignores the setting of the units and always returns the angle relative to the horizontal axis with 0 degrees facing the east, or three-o'clock position. The INITGET function may be used with both GETANGLE and GETORIENT to limit the user input to non-nil, non-0 angles. INITGET may also be used to change the rubber band line from the normally solid line to a dashed line."
The GETKWORD function allows you to limit the users input to a certain list of keywords. The INITGET function is used to set up the input that the GETKWORD function will accept.

(INITGET 1 "#4 #5 #6 #8 #10 1/4 5/16 3/8 7/16 1/2 5/8 3/4 7/8 1")
(GETKWORD "\nSize of socket head cap screw: ")

Any number of items may be passed to the INITGET function. All items must be on the same line in your program; anything on a separate line will not be read.

Input from a file

Opening / closing a file
The open function is used to open a file for use by your program. Before you can use a file for either input or output the file must be opened. You will set a variable, which will be a file pointer to the actual file being used.
Files may be opened in one of three modes: Read, Write, or Append. The open function needs two parameters passed to it. The first parameter tells it which file to open and the second parameter tells it what mode to open it in.

(setq fp (open "filename" "r"))

Filenames must be written in a specific manner for AutoLISP to understand what you are telling it. As was stated in a previous lesson, the backslash character has special meaning to AutoLISP and cannot be used by itself as you normally would when writing a path. Notice the use of double backslashes in the below example, this is how you would write a path using backslashes in AutoLISP. If you are going to write a path with your filename, one of the three methods must be used.

(setq fp (open "c:\\acad\\filename.ext" "r"))
(setq fp (open "c:/acad/filename.ext" "r"))
(setq fp (open (findfile "filename.ext") "r"))

The last example shows the use of the FINDFILE function. This function may be used to find a file that is in the AutoCAD environment path. If the file is not found it will return nil, so be sure to check whether it found the file before you try to use the file or it will crash your program.
When you are finished using a file it will need to be closed. The close function is used to close any files you may have opened earlier. If you don’t close files when you are done with them you will be using memory that could be used for opening other files for use.
Once a file is closed it cannot be reused until it is reopened. This is true even if the file pointer still exists; you must reopen the file before using it, once it has been closed.

Reading data from a file
The READ-CHAR or READ-LINE functions are used for reading data in from a file. The file must be an ASCII text file. Both of these functions return data of the string type.
If you have a file that you want to read one character at a time you would use the READ-CHAR function. It will read a file and return the ASCII character code for that character. You can find the end of the line by hunting for the carriage return character. Remember, once the carriage return character has been found to read one more character before starting processing on the next line or the first character you will get will be the line feed. Lines in ASCII files are terminated with the carriage return / line feed combination.
If you wish to read an entire line at a time, you would use the READ-LINE function. As I stated in the previous paragraph a line of ASCII text is terminated with the carriage return / line feed combination, and this is what read-line hunts for.

(setq LineIn (read-line fp))

Writing data to a file
The WRITE-CHAR or WRITE-LINE functions are used to put data into a file for later use. As with the reading functions, the file must first be opened according to the rules for opening a file.
The WRITE-CHAR function will output the ASCII character codes, of whatever characters you are writing out, to the file, which is currently open. It will build a file of characters with no carriage returns or line feeds.
The WRITE-LINE function will output an ASCII character string to the file, which is currently open. Each time the WRITE-LINE function is called it will write a new line to the file. If the file was opened in "append" mode, the line will be added to the end of the file. If the file was opened in "write" mode, the file will be overwritten with the new line.

(write-line LineOut fp)

Writing to the display
AutoLISP has a very powerful set of functions for controlling the display. The prompt function is the basic output function for use with AutoLISP. It will output a string to the display. It is the only prompting function that outputs only to the display.
The PRINC function may be used to output a string either to the display or to a file. It evaluates an expression and returns the results either to the display or to a file.
The PRINT function may be used to output a string either to the display or to a file. It evaluates an expression and returns the results either to the display or to a file with control characters included using the "\" format.
The PRINT function may be used to output a string either to the display or to a file. It evaluates an expression and returns the results either to the display or to a file, with a new line preceding the result and a space following it. Control characters included using the "\" format.
The TERPRI character outputs a new line only. There are no parameters that may be passed to this function.
The functions described above should be tried in different combinations so that when you need a certain output you will know which function will give the desired results. This is an area where experimentation will pay off later by getting you the output you are seeking.
If you have ansi.sys loaded in your computers configuration files, there are other things you can do to control your display. I am not in favor of using ansi.sys as a general means of programming, due to the fact that if you are writing your programs for use by people other than those in your company, they may or may not have ansi.sys loaded. If the people who use your programs are not captive to your company and don’t have ansi.sys loaded, all they will get on their screens are some strange characters, and this is not what they want to see. Use ansi.sys with care.
To use ansi.sys to control the screen display you will need to use the escape sequence of characters as

(prompt "\e[2J")

The code can be used to clear the screen. To learn the best ways of using ansi.sys will also take some practice, so setting aside some time to practice will be well worth the effort spent.

The ansi.sys codes are listed here
Screen function Ansi.sys Command
Clear the screen Esc [2J
Move to the new position Esc [#,#H
Cursor forward (Right) Esc [1C
Cursor back (Left) Esc [1D
Cursor up Esc [1A
Cursor down Esc [1B

Using combinations of the functions shown here, you will be able to get your user interface looking just how you want.

End of AutoLISP lesson