Chapter 14 - Example Programs WHY THIS CHAPTER? Although every program in this tutorial has been a complete program, each one has also been a very small program intended to teach you some principle of programming in C. It would do you a disservice to leave you at that point without introducing you to a few larger programs to illustrate how to put together the constructs you have learned to create a major program. This chapter contains four programs of increasing complexity, each designed to take you into a higher plateau of programming, and each designed to be useful to you in some way. DOSEX will illustrate how to make DOS system calls and will teach you, through self-study, how the system responds to the keyboard. WHATNEXT reads commands input on the command line and will aid you in setting up a variable batch file, one that requests an operator input and responds to the input by branching to a different part of the batch file. LIST is the source code for the program you used to print out the C source files when you began studying C with the aid of this tutorial. Finally we come to VC, the Visual Calculator, which you should find to be a useful program even if you don't study its source code. VC uses most of the programming techniques we have studied in this course and a few that we never even mentioned such as separately compiled subroutines. We will take a look at the example programs one at a time but without a complete explanation of any of them because you have been studying C for some time now and should be able to read and understand most of these programs on your own. DOSEX.C - The DOS Example Program The copy of DOS that you received with your IBM-PC or compatible has about 50 internal DOS calls that you can use as a programmer to control your peripheral devices and read information or status from them. Some of the earlier IBM DOS manuals, DOS 2.0 and earlier, have these calls listed in the back of the manual along with how to use them. Most of the manuals supplied with compatible computers make no mention of these calls even though they are extremely useful. These calls can be accessed from nearly any programming language but they do require some initial study to learn how to use them. This program is intended to aid you in this study. Page 97 Chapter 14 - Example Programs Display the program on your monitor or print it out for reference. It is merely a loop watching for a keyboard input or a change in the time. If either happens, it reacts accordingly. In line 32, the function "kbhit()" returns a value of 1 if a key has been hit but not yet read from the input buffer by the program. Look at the function named "get_time" for an example of a DOS call. An interrupt 21(hex) is called after setting the AH register to 2C(hex) = 44(decimal). The time is returned in the CH, CL, and DH registers. Refer to the DOS call definitions in your copy of DOS. If the definitions are not included there, Peter Nortons book, "Programmers Guide to the IBM PC" is recommended as a good reference manual for these calls and many other programming techniques. Note that Turbo C has a function named "gettime" that does the same thing. You should spend some time studying the Turbo C Reference Guide to learn of the availability of such functions. Another useful function is the "pos_cursor()" function that positions the cursor anywhere on the monitor that you desire by using a DOS interrupt. In this case, the interrupt used is 10(hex) which is the general monitor interrupt. This particular service is number 2 of about 10 different monitor services available. This function is included here as another example to you. The next function, service number 6 of interrupt 10(hex) is the window scroll service. It should be self explanatory. In this program, the cursor is positioned and some data is output to the monitor, then the cursor is "hidden" by moving it to line 26 which is not displayed. After you compile and run the program, you will notice that the cursor is not visible on the monitor. This is possible in any program, but be sure to put the cursor in view before returning to DOS because DOS does not like to have a "hidden" cursor and may do some strange things. Some time spent studying this program will be valuable to you as it will reveal how the keyboard data is input to the computer. Especially of importance is how the special keys such as function keys, arrows, etc. are handled. Also note that this program uses full prototype checking and is a good example of how to use it. Since it also uses the "modern" method of function definitions, it is a good example of that also. Page 98 Chapter 14 - Example Programs WHATNEXT.C - The Batch File Interrogator This is an example of how to read the data on the command line following the function call. Notice that there are two variables listed within the parentheses following the main() call. The first variable is a count of words in the entire command line including the command itself and the second variable is a pointer to an array of pointers defining the actual words on the command line. First the question on the command line, made up of some number of words, is displayed on the monitor and the program waits for the operator to hit a key. If the key hit is one of those in the last "word" of the group of words on the command line, the number of the character within the group is returned to the program where it can be tested with the "errorlevel" command in the batch file. You could use this technique to create a variable AUTOEXEC.BAT file or any other batch file can use this for a many way branch. Compile and run this file with TEST.BAT for an example of how it works in practice. You may find this technique useful in one of your batch files and you will almost certainly need to read in the command line parameters someday. An interesting alternative would be for you to write a program named "WOULD.C" that would return a 1 if a "Y" or "y" were typed and a zero if any other key were hit. Then your batch file could have a line such as; WOULD YOU LIKE TO USE THE ALTERNATIVE METHOD (Y/N) Dos would use "WOULD" as the program name, ignore the rest of the statement except for displaying it on the screen. You would then respond to the question on the monitor with a single keyhit. Your batch file would then respond to the 1 or 0 returned and either run the alternative part of the batch file or the primary part whatever each part was. WOULD YOU LIKE PRIMARY (Y/N) IF ERRORLEVEL 1 GOTO PRIMARY (secondary commands) GOTO DONE :PRIMARY (primary commands) :DONE Page 99 Chapter 14 - Example Programs LIST.C - The Program Lister This program is actually composed of two files, LIST.C and LISTF.C that must be separately compiled and linked together with your linker. There is nothing new here and you should have no trouble compiling and linking this program by reading the documentation supplied with your Turbo C compiler. A LIST.PRJ file is included on the SOURCE disk of the tutorial as an aid to you in compiling and linking this program. Read pages 62 and 63 of the Turbo C Users Guide for instructions on how to do it. The only thing that is new in this program is the inclusion of three "extern" variables in the LISTF.C listing. The only purpose for this is to tie these global variables to the main program and tell the compiler that these are not new variables. The compiler will therefore not generate any new storage space for them but simply use their names during the compile process. At link time, the linker will get their actual storage locations from the LIST.OBJ file and use those locations for the variables in the LISTF part of the memory map also. The variables of those names in both files are therefore the same identical variables and can be used just as any other global variables could be used if both parts of the program were in one file. There is no reason why the variables couldn't have been defined in the LISTF.C part of the program and declared as "extern" in the LIST.C part. Some of the variables could have been defined in one and some in the other. It is merely a matter of personal taste. Carried to an extreme, all of the variables could have been defined in a third file and named "extern" in both of these files. The third file would then be compiled and included in the linking process. It would be to your advantage to compile, link, and run this program to prepare you for the next program which is composed of 6 separate files which must all work together. VC.C - The Visual Calculator This program finally ties nearly everything together because it uses nearly every concept covered in the entire tutorial. It is so big that I will not even try to cover the finer points of its operation. Only a few of the more important points will be discussed. The first thing you should do is go through the tutorial for VC included in the file VC.DOC. There are Page 100 Chapter 14 - Example Programs several dozen steps for you to execute, with each step illustrating some aspect of the Visual Calculator. You will get a good feel for what it is capable of doing and make your study of the source code very profitable. In addition, you will probably find many ways to use the Visual Calculator to solve problems involving calculations where the simplicity of the problem at hand does not warrant writing a program. Notice that the structure definitions, used in all of the separate parts of the program, are defined in the file STRUCT.DEF. During program development, when it became necessary to change one of the structures slightly, it was not necessary to change it in all of the files, only one file required modification which was then "included" in the source files. Notice that the transcript data is stored in a doubly linked list with the data itself being stored in a separate dynamically allocated char string. This line is pointed to by the pointer "lineloc". For ease of development, the similar functions were grouped together and compiled separately. Thus, all of the functions involving the monitor were included in the file named VIDEO.C, and all of the functions involving the data storage were grouped into the FILE.C collection. Dividing your program in a way similar to this should simplify debugging and future modifications. Of special interest is the "monitor()" function. This function examines the video mode through use of a DOS command and if it is a 7, it assumes it is a monochrome monitor, otherwise it assumes a color monitor. The colors of the various fields are established at this time and used throughout the program. Most of the data is written directly to the video memory, but some is written through the standard BIOS routines. The file DEFIN.H is a catalogue of the functions to aid in finding the functions. This file was generated as one of the first files and was maintained and updated for use during the entire design and coding lifetime. It also contains all of the prototype definitions for the functions in all of the source files, and is "included" in every source file to do prototype checking. The file VC.PRJ is included as an aid for you to compile and link this program. The Visual Calculator is supplied to you as VC.EXE already compiled and linked for you. Feel free, after understanding this code, to modify it in any way you desire for your own use. Page 101