Objects First |
Then we'll examine the problem of formally testing the class methods.
Click here to load the first test program.
As usual, we have a prologue, import statements and some constants defined for this program.
So we started writing this program by writing some software tools - functions that encapsulated a set of useful operations (reading and parsing lines from the file and loading them into the dictionary) into one function. This has the effect of making the main function extremely simple and easy to understand.
There are two of these tool routines here, ParseLine which parses the input line into its constituent words, and LoadDictionary which opens the file, reads lines, calls ParseLine to parse them and then adds the words to the dictionary.
For the moment, let's skip over ParseLine to LoadDictionary.
int LoadDictionary( Dictionary d, char *file_name );We've added assert's to the function to check pre-conditions - even though we haven't bothered to provide a formal specification of this function as we would do for a class method, we don't abandon our good robust programming habits and leave the assert's behind! In fact there's no reason why we couldn't move it into the class itself as a method that loads a dictionary from a file - a perfectly legitimate class method!
Working through this function, line by line --
after the asserts, we initialise the count of words added
to the dictionary to 0.
Then we try to read the file, we've put the words and their translations in a text file (we prepared it with a text editor), so we use the stream I/O routines, fopen, fclose, fgets, ... The file's name is in the string, file_name, passed as an argument, so we pass it to fopen along with a second argument, "r", which tells fopen that we want to read the file. If fopen can open the file for us, it will return a file handle of type FILE *, which we store in the variable, f. Remember that we can consider fopen as a constructor for the input stream of data from the file. It returns an object (the data stream) that we can manipulate with fgets, etc.
If the file doesn't exist or can't be read, or any other system error occurs, then fopen will return a NULL. In this case, we jump to the else branch of this if and print a suitable message.
The translations are stored in the file one translation (English word; foreign word) to a line. Therefore we use fgets to read lines one at a time into the buffer buf. Note how we carefully used a symbolic constant, BUF_LEN, to declare the array: char buf[BUF_LEN] and here in the call to fgets.
If fgets tries to read past the end of the file, it will return a NULL. So the while( fgets(..) != NULL ) loop conveniently reads lines from the file, one by one, and exits from the loop at the end of the file.
|
Continue on to Verifying the Dictionary Class Back to the Table of Contents |