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. This course was originally written for use on an IBM-PC or compatible running the PC-DOS operating system. Some of the example programs in this chapter will not compile and execute properly if you are using some other computer or operating system, but the techniques may still be useful to you. It would be advantageous to you to spend some time studying these programs regardless of what computer you are using. 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 C source code for a program that operates similarly to the listing 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 80 internal DOS calls that you can use Page 14-1 Chapter 14 - Example Programs 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. Display the program on your monitor or print ============= it out for reference. It is merely a loop DOSEX.C 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 Norton's book, "Programmers Guide to the IBM PC" is recommended as a good reference manual for these calls and many other programming techniques. Your compiler may have a built in function to do this. If you read your documentation, you will probably find many useful functions available with your compiler that are included as a convenience for you by your compiler writer. 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 Page 14-2 Chapter 14 - Example Programs 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. WHATNEXT.C - The Batch File Interrogator ____________________________________________________________ This is an example of how to read the data on ============== the command line following the function call. WHATNEXT.C 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 14-3 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 LIST.C 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 C compiler. 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 VC.C 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 several dozen steps for you to execute, with each step illustrating some aspect Page 14-4 Chapter 14 - Example Programs 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 VC.DOC 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 character 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 function named monitor(). 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. Page 14-5