home *** CD-ROM | disk | FTP | other *** search
- Chapter 8 - Input/Output
-
-
- A SIMPLE OUTPUT PROGRAM
-
- Load and display the file named SIMPLOUT.MOD for an
- example of the simple output functions. This program is
- limited to writing only to the monitor but we will get to
- files and printer output shortly. We must first establish
- some basic principles for use with library procedures.
-
- The first line of the declaration part of the program
- imports our two familiar procedures "WriteString" and
- "WriteLn" in the same manner we are used to. The next line
- imports every procedure in "InOut" and makes them available
- for use in the program without specifically naming each one
- in the IMPORT list. The third line imports every procedure
- from "Terminal" so that they too are available for our use.
- The procedures that are imported explicitly can be used in
- exactly the same manner that we have been using them all
- along, simply name the procedure with any arguments they
- use. The others can only be used with a "qualifier" that
- tells which library module they come from.
-
- An example is the easiest way to describe their use so
- refer to the program before you. Line 11 uses the
- explicitly defined procedure from "InOut", line 12 uses the
- same procedure from "InOut", and line 15 uses the procedure
- of the same name from "Terminal". Line 11 uses the
- unqualified procedure call from "InOut", and lines 12 and 15
- use the qualified method of calling the procedures from both
- library modules.
-
- In this case, the two procedures do the same thing, but
- it is not required that procedures with the same name do the
- same thing. By adding the library module name to the front
- of the procedure name with a period between them, we tell
- the system which of the two procedures we wish to use. If
- we tried to explicitly import both "WriteString" procedures
- we would get a compile error, so this is the way to use the
- same name twice.
-
- WHAT IS A LIBRARY MODULE?
-
- What I have been calling a library module is more
- properly termed a "module" and is the biggest benefit that
- Modula-2 enjoys over other programming languages. This is
- the quality that gives Modula-2 the ability to have
- separately compiled modules, because a module is a
- compilation unit. When you get to Part III of this
- tutorial, you will learn how to write your own modules
- containing your own favorite procedures, and call them in
- any program in the same manner that you have been calling
- the procedures provided by your compiler writer.
-
-
- Page 49
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
-
- None of the procedures you have been importing are part
- of the Modula-2 language, they are extensions to the
- language provided for you by your compiler writer. Since
- they are not standard parts of the language, they may vary
- from compiler to compiler. For that reason, I have tried to
- use those defined by Niklaus Wirth in his definition of the
- language, and no others.
-
- STUDY YOUR REFERENCE MANUAL
-
- This would be a good place for you to stop and spend
- some time reading your reference manual. Look up the
- section in your manual that is probably called the "Library"
- and read through some of the details given there. You will
- find that there are many things listed there that you will
- not understand at this point, but you will also find many
- things there that you do understand. Each module will have
- a number of procedures that are "exported" so that you can
- "import" them and use them. Each procedure will have a
- definition of what arguments are required in order to use
- it. Most of these definitions should be understandable to
- you. One thing you will find is that only the "PROCEDURE
- procname;" is given along with the arguments, with the
- actual code of the procedure omitted. We will study about
- this in "Part III" also. The part that is shown is the
- "DEFINITION MODULE" which only gives the calling
- requirements. The "IMPLEMENTATION MODULE" which gives the
- actual program code of the procedure is usually not given by
- compiler writers.
-
- As you study the library modules, you will find
- procedures to handle strings, variables and conversions
- between the two. You will find "mouse" drivers, "BIOS"
- calls to the inner workings of your operating system, and
- many other kinds of procedures. All of these procedures are
- available for you to use in your programs. They have been
- written, debugged, and documented for your use once you
- learn to use them. In addition, you will have the ability
- to add to this list by creating your own modules containing
- your own procedures.
-
- BACK TO THE PROGRAM "SIMPLOUT"
-
- Notice that in lines 13, 17, and 22, three different
- ways are used to call "WriteLn", even though there are
- actually only two procedures (that happen to do the same
- thing). A little time spent here will be time well spent in
- preparing for the next few programs. When you think you
- understand this program, compile and run it.
-
-
-
- Page 50
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- NOW FOR SOME SIMPLE INPUT PROCEDURES
-
- Load the program named SIMPLIN.MOD for our first
- example of a program with some data input procedures. In
- every program we have run so far in this tutorial, all data
- has been stored right in the program statements. It would
- be a very sad computer that did not have the ability to read
- variable data in from the keyboard and files. This program
- is our first that can read from an external device, and it
- will be limited to only the keyboard.
-
- This program is broken up into four groups of
- statements, each illustrating some aspect of reading data
- from the keyboard. This could have been four separate files
- but it will be easier to compile and run one file.
-
- Beginning with line 14 we have an example of the
- "ReadString" procedure which reads characters until it
- receives a space, a tab, a return, or some other
- nonprintable character. This loop will read three words on
- one line, one word on each of three lines, or any
- combination to get three words of groups of printable ASCII
- characters. After each word or group is read, it is simply
- "printed" to the monitor for your inspection.
-
- ONE CHARACTER AT A TIME
-
- The next group of statements is a loop in which 50
- ASCII characters are read in and immediately echoed out to
- the monitor. It should be evident to you that the
- characters are read one at a time, and since the same
- variable is used for each character, they are not stored or
- saved in any way. In actual practice, the characters would
- be stored for whatever purpose you intend to use them for.
- When you run this part of the program, it will seem like the
- computer is simply acting like a word processor, echoing
- your input back to the monitor.
-
- ONE LINE AT A TIME
-
- The next section, beginning in line 32, reads in a full
- line before writing it out to the monitor. In this program
- we are introduced to the "EOL" which is a constant defined
- by the system for our use. It must be imported from "InOut"
- just like the procedures are, and it is a constant that is
- equal to that ASCII value that is returned when we hit the
- "return" key. It is therefore equal to the End-Of-Line
- character, and that is how it got its name. If we compare
- the input character to it, we can determine when we get to
- the End-Of-Line. That is exactly what this loop does. It
- continues to read characters until we find an EOL, then it
-
-
- Page 51
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- terminates the input loop and displays the line of data.
- Notice that this time we do not simply read the data and
- ignore it but instead add it character by character to the
- ARRAY named "StringOfData". Of course, the next time
- through the loop we overwrite it. The careful student will
- also notice that, in line 45 we wrote a zero character in
- the character of the line just past the end of the line.
- The zero is to indicate the end-of-string for the string
- handling procedures. This portion of the program is easy,
- but will require a little time on your part to completely
- dissect it.
-
- READING IN SOME NUMBERS, CARDINAL
-
- Beginning in line 51, we have an example of reading 6
- CARDINAL numbers in a loop. The procedure "ReadCard" will,
- when invoked by your program, read as many digits as you
- give it. When it reads any character other than a 0 through
- 9, it will terminate and return the number to your calling
- program. Notice that this time all 6 numbers are read in,
- stored, and when all are in, they are all displayed on one
- line. This should be easy for you to decipher.
-
- COMPILING AND RUNNING THIS PROGRAM
-
- There is no program that you have studied here that is
- as important for you to compile and run as this one is. You
- should spend considerable time running this program and
- comparing the results with the listing. Enter some invalid
- data when you are running the "ReadCard" portion of it to
- see what it does. When you are running the "line at a time"
- portion, try to enter more than 80 characters to see what it
- will do with it. This is a good point for you to learn what
- happens when errors occur. After you understand what this
- program does, we will proceed to file input and output.
-
- FILE INPUT/OUTPUT
-
- Load and display the file named FILEIO.MOD for your
- first file reading and writing. The library module named
- "InOut" has the ability to either read and write from/to the
- keyboard and monitor, or to read and write from/to files.
- The program before you redirects the input and output to
- files for an illustration of how to do it.
-
- Line 16 requests the operator, namely you, to enter a
- filename to be used for input. There is nothing different
- about this statement than the others you have been using.
- The next line requests the system to open a file for
- inputting, and part of the procedure "OpenInput" is to go to
- the keyboard waiting for the filename to be typed in. So
-
-
- Page 52
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- the message in line 16 is in preparation for what we know
- will happen in line 17. Whatever filename is typed in is
- opened for reading if it is found on the disk. The "MOD" in
- the parentheses is a default extension supplied, (this can
- be any extension you desire). If no extension is supplied
- by the operator, and if the filename does not have a "."
- following it, ".MOD" will be added to the filename. If the
- system can find the requested filename.extension, the "Done"
- flag is made TRUE and we can test it. In this example, if
- the flag is returned FALSE, we ask the operator to try again
- until he finally inputs a filename that exists on the
- default disk/directory.
-
- NOW TO OPEN AN OUTPUT FILE
-
- Once again, in line 21, we request a filename for
- output anticipating the operation of the "OpenOutput" in
- line 22. Line 22 waits for a keyboard input of a filename
- and if the filename entered has no extension, it adds the
- extension ".DOG" and attempts to open the file for writing.
- When you input the filename, adding a "." to the end of the
- filename will prevent the extension being added. If the
- Filename.extension does not exist, it will be created for
- you. If it does exist, it's contents will be erased.
-
- It is nearly assured that the file will be created and
- the "Done" flag will be supplied as TRUE, but it would be
- good practice to check the flag anyway. It will be apparent
- when we get to the program on printer output, that it is
- impossible to open a file with certain names, one being
- "PRN", because the name is reserved for printer
- identification and the "Done" flag will be returned FALSE.
-
- HOW DO I USE THE OPENED FILES?
-
- Anytime you use this technique to open a file for
- writing, any procedure from InOut will now be redirected to
- that file. Anytime you use this technique to open a file
- for reading, any procedure from InOut will access the file
- named instead of the keyboard. In addition, the library
- module named "RealInOut" will also be redirected with
- "InOut". Any time you read or write, instead of using the
- keyboard and monitor, the input and output files will be
- used. The input and output will be the same except for
- where it goes to and comes from, and it is possible to only
- open one and leave the other intact. Thus input can be from
- a file, and output can still go to the monitor.
-
- When I/O is redirected, the module "Terminal" is still
- available for use with the monitor and keyboard as I/O using
- this module can not be redirected. The module named
-
-
- Page 53
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- "Terminal" does not have the flexibility of input and output
- that is found in "InOut" so it is a little more difficult to
- use.
-
- There is a major drawback when using "InOut" with the I/O
- redirected. You are limited to one file for input and one
- file for output at one time. Finally, this method cannot be
- used to open a "fixed" or prenamed file, since it always
- surveys the keyboard for the filename. It will probably
- come as no surprise to you that all of these limitations
- will be overcome with another method given in the next two
- programs.
-
- The program itself should be easy to follow, once you
- realize that the flag named "Done" returns TRUE when a valid
- character is found following a "Read", and FALSE when an
- End-Of-File (EOF) is detected. The "Done" flag is set up
- following each operation so its use is dictated by which
- procedure was called last. The program simply copies all
- characters from one file to another. When completed, the
- two procedures named "CloseInput" and "CloseOutput" are
- called to do just that, to close the files and once again
- make the I/O available to the keyboard and monitor. In this
- case, however, we immediately terminate the program without
- taking advantage of the return to normal.
-
- Compile and run this program, being careful not to give
- it the name of an existing file for output, or it will
- overwrite the old data in the file and copy new data into
- it. That is the reason for the extension "DOG". Few people
- will have a file with that extension. For input, use the
- present filename (FILEIO.MOD), for output, use "STUFF",
- "STUFF.", and "STUFF.STU", observing the resulting new
- filename each time.
-
- THE COMPLETE FILESYSTEM
-
- Load and display the file named VARYFILE.MOD for an
- example using the complete "FileSystem" module. As stated
- earlier, Modula-2 does not have any input/output methods
- defined as part of the language. This is because the I/O
- available on computers is so diverse, there would be no way
- of defining a method that could be used on all computers.
- To eliminate the problem, Niklaus Wirth simply defined no
- I/O as part of the language, but he did suggest a few
- standard modules to perform the basic I/O tasks. Since they
- are only suggestions, compiler writers are not constrained
- to follow them, but in the interest of portability, most
- will. A very limited subset of all of the procedures are
- the only ones that will be used in the tutorial portion of
- this course. (A few other procedures will be used in the
-
-
- Page 54
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- example programs given in those chapters.) It will be up to
- you to see that the procedures are in order with your
- compiler, and where they differ, to modify them. A few
- notes are available for your assistance in the COMPILER.DOC
- file on your distribution disk for those compilers available
- at the time of release of this tutorial.
-
- BACK TO THE PROGRAM NAMED VARYFILE
-
- This time we IMPORT several procedures from the library
- module named "FileSystem" for I/O use. This time, we ask
- for the input filename and store it internally in a string
- variable. This implies that we can also define the filename
- as a constant that is carried in the program, making it
- possible to use a certain preprogrammed filename for input.
- We use the procedure "Lookup" to open the file. This
- procedure uses three arguments within the parentheses, the
- first being the symbolic filename which is a record of
- information about the file. (We will come to records later,
- don't worry too much about it at this point.) The second
-
- argument is the name of the file on disk we wish to access,
- and the third argument is a boolean variable or constant.
- If it is TRUE, and the file name is not found, a new file of
- that name will be created. If it is FALSE, and the file is
- not found, a new file will not be created, and the record
- variable "InFile.res" will return the value "notdone".
- (That refers to one variable named "res" which is a part of
- the record "InFile".)
-
- Note that the variable "InFile", is a record composed
- of many parts, but for the immediate future we only need to
- be concerned with its definition. It is defined as a
- variable of type "File" which is imported from the module
- named "FileSystem". Until you study the lesson in this
- tutorial on records, simply copy the method used here for
- file Input/Output.
-
- Once the file is opened, you can use any of the
- procedures included in the "FileSystem" module, being
- careful to follow the rules given in your library
- documentation. The remainder of the program should be self-
- explanatory and will be left to your inspection. With this
- example in hand, spend some time studying your "FileSystem"
- module to become familiar with it, then compile the program
- and run it to observe its operation.
-
- NOW FOR MULTIPLE FILE OPERATIONS
-
- Load and display the file named PRINTFLE.MOD for an
- example program that uses 4 files at once, and still writes
- to the monitor. This program is very similar to the last in
-
-
- Page 55
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- that it opens one file for reading, but it opens three files
- for writing. Each of the four files has its own identifier,
- a record of type "File", and each has its own filename. The
- three output files are firmly fixed to certain filenames,
- rather than ask the operator for names, and the third
- filename is a very special name, "PRN". This is not a file
- but is the access to the printer. Anything written to this
- file will go to your line printer, so you should turn your
- printer on in anticipation of running it. Your compiler may
- also allow a few other names such as "LPT0", "LPT1", etc,
- and there may be other names reserved for serial I/O such as
- to talk to a modem, a joystick, etc. You will need to
- consult your compiler documentation for a complete list of
- special names.
-
-
- The program itself is very simple and similar to the
- last one. A character is read from the input file, and
- output to the three output files and to the monitor. In the
- case of "CapFile", the character is capitalized before it is
- output simply to indicate to you that the files are indeed
- different. Study it until you understand it, then compile
- and run it. Look at the contents of the new files to see if
- they are correct.
-
- MORE NEAT THINGS WE CAN DO WITH FILES
-
- There are many more things that you can do with the
- "FileSystem" module. It is possible to open a file, begin
- reading until you come to a selected position, and change to
- a write file to overwrite some of the data with new data.
- You can write to a file, change it to a read file, reset it
- to the beginning, and read the data back out. You can
- rename a file, or delete it. It will be up to you to study
- the documentation for your "FileSystem" module, and learn
- how to use it effectively.
-
- YOU ARE AT A SPECIAL POINT IN MODULA-2
-
- With the completion of this chapter, you have arrived
- at a very special point in your study of Modula-2. Many
- people arrive at this point in a language and quit studying,
- preferring to use the language in a somewhat limited sense
- rather than to go on and learn the advanced topics. If your
- needs are few, you can quit here also and be well assured
- that you can write many programs with Modula-2. In fact
- there will be very few times when you cannot do all that you
- wish to do. However, if you choose to go on to the advanced
- topics, you will find that some of the programming chores
- will be greatly simplified.
-
-
-
- Page 56
-
-
-
-
-
-
-
-
-
- Chapter 8 - Input/Output
-
-
- Whether you decide to go on to the advanced topics or
- not, it would be wise for you to stop at this point and
- begin using what you have learned to actually write some
- programs for your own personal use. Everybody has need
- occasionally for a program to do some sort of translation of
- data in a text file for example. Write programs to do some
- data shuffling from file to file changing the format in some
- way. You should be able to think up several programs that
- you would find useful.
-
- Spend some time studying and running the programs in
- the next chapter, then modify them to suit your needs,
- building up a few utilities for your software collection.
- The best way to learn to program is to program. You have
- all of the tools you need to get started, so you would do
- well to get started. Adding some programming experience
- will be a big help if you decide to continue your study into
- the advanced features of Modula-2.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 57
-