What You Need to Know Specifically for this Program ---- --- ---- -- ---- ------------ --- ---- ------- Below is a general discussion of the Text_IO package including a description of how to instantiate a generic IO package so that you can input and output integers or floats, something you don't need to do for this assignment. What you do need to know for this assignment is how to test for the end-of-file (simulated by ctrl-D on the key board). Below is an example of a loop that reads until the end-of-file is encountered. while( not END_OF_FILE ) loop if ( END_OF_LINE ) then . . . end if; end loop; The body of the loop also demonstrates the END_OF_LINE function. Both END_OF_FILE and END_OF_LINE are in the package Text_IO. General Information on The Package TEXT_IO ------- ----------- -- --- ------- ------- The package TEXT_IO is predefined and contains operations for input and output of character, numeric and enumeration type values. In Ada, a text file is viewed as a sequence of pages, a page is a sequence of lines, and a line is a sequence of characters. Below are some entities declared in the package TEXT_IO. FILE MANAGEMENT: type FILE_TYPE is ... (don't worry about this for now); -- the type you use for declaring files type FILE_MODE is (IN_FILE, OUT_FILE); -- IN_FILE is for GETs, OUT_FILE is for PUTs type COUNT is range 0 .. (some number); subtype POSITIVE_COUNT is COUNT range 1..COUNT'LAST; -- these types are for column, line and page number parameters type FIELD is range 0 .. (some number); -- this is the type for valid field widths, for numeric IO procedure CREATE(FILE : in out FILE_TYPE; -- the file to create MODE: in FILE_MODE := OUT_FILE; -- the access mode NAME: in STRING := ""; -- the file name FORM: in STRING := "" -- implementation dependnt ); -- creates a new file (to write to), and leaves it open procedure OPEN(FILE : in out FILE_TYPE; -- the file to open MODE: in FILE_MODE; -- the access mode NAME: in STRING := ""; -- the file name FORM: in STRING := "" -- implementation dependnt ); -- opens an existing file for input/output, depending on MODE -- raises STATUS_ERROR if file already open -- raises NAME_ERROR if file can not be found -- raises USE_ERROR if the system is protecting the file procedure CLOSE(FILE: in out FILE_TYPE); -- closes the file, disallowing I/O on it procedure RESET(FILE: in out FILE_TYPE); -- resets the file so that reading/writing will occur at the beginning -- (i.e., allows files to be read multiple times) Most I/O procedures are overloaded so that there is a version which operates on a specified file, and one which operates on the "default" file. To set the default input or output file to a particular file, use procedure SET_INPUT(FILE: in FILE_TYPE); procedure SET_OUTPUT(FILE: in FILE_TYPE); In addition, the package contains some routines for testing and controlling lines and pages. procedure NEW_LINE(FILE: in FILE_TYPE; SPACING: in POSITIVE_COUNT := 1); procedure NEW_LINE(SPACING: in POSITIVE_COUNT := 1); -- writes SPACING line terminators to the output file procedure SKIP_LINE(FILE: in FILE_TYPE; SPACING: in POSITIVE_COUNT := 1); procedure SKIP_LINE(SPACING: in POSITIVE_COUNT := 1); -- skips over SPACING line terminators in the input file procedure NEW_PAGE(FILE: in FILE_TYPE); procedure NEW_PAGE; -- writes a page terminator to the output function END_OF_LINE(FILE: in FILE_TYPE) return BOOLEAN; function END_OF_LINE return BOOLEAN; -- Are we about to read a line terminator? function END_OF_FILE(FILE: in FILE_TYPE) return BOOLEAN; function END_OF_FILE return BOOLEAN; -- Are we at the end of a file? CHARACTER I/O: Next are the GET and PUT routines. All GET routines raise the exception END_ERROR when END_OF_FILE becomes true while trying to read an item. procedure GET(FILE: in FILE_TYPE; ITEM: out CHARACTER); procedure GET(ITEM: out CHARACTER); -- Skips over terminators, reads the next character into ITEM procedure PUT(FILE: in FILE_TYPE; ITEM: in CHARACTER); procedure PUT(ITEM: in CHARACTER); -- Adds the ITEM to the current line of output procedure GET(FILE: in FILE_TYPE; ITEM: out STRING); procedure GET(ITEM: out STRING); -- PERFORMS successive character GETs to fill the STRING variable procedure PUT(FILE: in FILE_TYPE; ITEM: in STRING); procedure PUT(ITEM: in STRING); -- Adds the string ITEM to the current line of output procedure PUT_LINE(FILE: in FILE_TYPE; ITEM: in STRING); procedure PUT_LINE(ITEM: in STRING); -- same as PUT followed by NEW_LINE NUMERIC I/O: For numeric and enumeration I/O, the package TEXT_IO defines "generic packages" which define those routines for arbitrary numeric types/subtypes. The name of the generic package for the family of INTEGER-based types is INTEGER_IO, and for FLOAT-based types is FLOAT_IO. The packages have a generic type parameter (called "NUM") on which all operations inside are based. E.g., INTEGER_IO has procedure GET(ITEM: out NUM; WIDTH: in FIELD := 0); which extracts the next NUM from the input and places it in ITEM; Since NUM is simply a parameter, the "real GET" is defined by filling in an integer type for NUM. Hence, the package INTEGER_IO is not a package at all, but is merely a "template" for defining INTEGER-based I/O routines of specified integer type NUM. So, before we use GET and PUT on INTEGER-based numbers of some type T (e.g., subtype T is INTEGER range 0..100;) you must define a new package using the INTEGER_IO template. We call this "instantiating" the generic package, because we specify an instance of it using a type for NUM. To do this, in your main program (as a basic declaration), place package SOME_NAME is new INTEGER_IO( T ); use SOME_NAME; This defines a new package called SOME_NAME which is the same as INTEGER_IO except with the type "T" filled in for the generic parameter "NUM". (A similar thing is required to do FLOAT-based I/O.) So, even if the type T is the full set of INTEGERs, we must do the same thing. Hence, a program which uses integer I/O routines and float I/O will begin like this: with TEXT_IO; use TEXT_IO; procedure MAIN is package INT_IO is new INTEGER_IO(INTEGER); use INT_IO; package FLO_IO is new FLOAT_IO(FLOAT); use FLO_IO; ... The integer and float I/O routines appear below. They, too, are overloaded to operate with and without a specified FILE. (Integer and Float) procedure GET(FILE: in FILE_TYPE; ITEM: out NUM; WIDTH: in FIELD := 0); -- Reads the next ITEM (a literal of type NUM) from the input -- If WIDTH > 0, then only WIDTH characters are read -- Raises DATA_ERROR if the input item scanned does not have the -- required syntax, or if not of the subtype NUM (Float) procedure PUT(FILE: in FILE_TYPE; ITEM: in NUM; FORE: in FIELD := DEFAULT_FORE; AFT: in FIELD := DEFAULT_AFT; EXP: in FIELD := DEFAULT_EXP); -- If EXP > 0, outputs ITEM in the form [-]d.E -- If EXP = 0, outputs ITEM in the form . -- where the FORE field allows for the possible '-' sign -- All values are right justified with leading blanks (Integer) procedure PUT(FILE: in FILE_TYPE; ITEM: in NUM; WIDTH: in FIELD := DEFAULT_WIDTH; BASE: in NUMBER_BASE := DEFAULT_BASE); -- Outputs ITEM, no leading zeros, with leading minus if negative -- Right justifies if WIDTH too large; extends WIDTH if too small -- Note: BASE is between 2 and 16. If BASE not 10 (the default), then -- outputs in the form BASE#ITEM#, as in Ada integer literals ENUMERATION I/O: The generic package ENUMERATION_IO allows reading and writing of enumeration type literals of a specified type ENUM. As in the numeric I/O, the programmer must instantiate this template with a specific enumeration type...e.g., type DAYS is (SUN, MON, TUE, WED, THU, FRI, SAT); ... package DAYS_IO is new ENUMERATION_IO(DAYS); use DAYS_IO; ... This allows one to use GETs and PUTs on items of type DAYS. Enumeration I/O routines appear below. They are also overloaded to take a FILE parameter, or to use the default file. procedure GET(FILE: in FILE_TYPE; ITEM: out ENUM); -- Reads the next ITEM (a literal of type ENUM) from the input -- Skips over leading blanks and terminators, and scans the literal -- Lower and upper case are equivalent in identifiers -- Raises DATA_ERROR if the input item scanned does not have the -- required syntax, or if not of the subtype NUM procedure PUT(FILE: in FILE_TYPE; ITEM: in ENUM; WIDTH: in FIELD := DEFAULT_WIDTH; SET: in TYPE_SET := DEFAULT_SETTING); -- Outputs ITEM as an enumeration literal (identifier or quoted char) -- Left justifies if WIDTH too large; extends WIDTH if too small -- Default WIDTH is 0 -- TYPE_SET is the type (LOWER_CASE, UPPER_CASE), and controls which -- case the identifiers will be displayed (default = UPPER_CASE)