Computer Science 2611
Fall 2004
Programming Assignment 5

Date assigned: 10/4/04


Designing versatile software

Ideally, you would like your software to be as versatile and easy to change as possible. One way to do that is to store some information about how the program should work in files that are not part of the program itself, and that are in a format that makes them easy to modify, even for people who do not know anything about writing programs.

This is how computer games work. A general program is written that can be used for many different games. Then the details of a particular game (what the background looks like, the different "rooms", how they are connnected to one another, what each character looks like (graphic files), each character's properties, etc.) are put into files that the general game software reads. To create a new game, all you have to do is create the graphics (usually done by artists) and the files that describe the places and characters of the game.


Your assignment

This assignment is to modify your solution to assignment 4 so that it reads words to replace from a file instead of having them built into the program. A file called pirate.txt will contain two words per line: the regular word followed by the "pirate" word. For example, it might have the following form.

is be
Is Be
are be
Are Be
drink quaff
and can be modified at any time. Your program should read this file, and then work as before. It should still put "Argh," at the beginning of each sentence.

You cannot build the number of lines in the pirate.txt file into your program. Your program must continue to work, without any modification, when more lines are added to that file.


Notes on how to write this program

 

Opening a file for reading

You can create an object that is tied to a given operating system file. It works just like cin, but instead of reading from the standard input, it reads from a file. Include <fstream> in your program. Then, to create a file object called in, and to tie it to file pirate.txt, write

  ifstream in;
  in.open("pirate.txt");
Be careful. The file that you are trying to open might not exist. Do not presume that everything will work out. Check whether the open operation was successful. You can use object in as a condition in an if-statement or while-statement. It is considered to be true if the last operation that you performed on it (including an open operation) was successful. So
  if(!in)
  {
    ...
  }
can be used just after the open operation to see whether the open was successful. If it was not, do not continue. You cannot perform your job if the pirate.txt file is missing.

 

Reading words

Use in just like you word cin. You can read a string (an array of characters) by creating the array, and just reading the array. For example,

  char word[MAX_WORD_SIZE];
  in >> word;
first skips over any "white-space" characters such as spaces, tabs and end-of-line markers, then reads characters until it hits another white-space character. It stores the characters that it reads (excluding the white-space characters) into array word, and adds a null character to the end.

Be sure that word is large enough. If it is not, you will go beyond the end of the array.

 

Detecting the end of the file

Each attempt to read from a file (or from the standard input) either succeeds or fails. Use the file object in a test. If the last operation succeeded, then the test will be true.

 

Storing all of the translations in a table

There can be many regular words and corresponding pirate words. You need to be able to have an array of regular words, and an array of pirate words. But each word is an array of characters. So you need an array of arrays. You can do that in C++. Create array

  char table[MAX_NUM_WORDS][MAX_WORD_SIZE];
to create an array table containing MAX_NUM_WORDS slots. Each slot in array table is an array of MAX_WORD_SIZE characters. Now
  table[0]
is the first of those slots. So it is an array of characters. If you write
  in >> table[0];
you will read an entire string into table[0].

Create two arrays, one to hold the regular words and one to hold the pirate words. After you read file pirate.txt, you might have the following one of your arrays.

Be sure to read information into both arrays. If your arrays are called regularWords and pirateWords, then the k-th regular word will be in regularWords[k], and the k-th pirate word will be in pirateWords[k].

 

Performing translations

Your translate function currently takes two parameters, the word to translate and an array where the result whould be put. Add more parameters to it.

  1. The array of regular words
  2. The array of pirate words
  3. The number of regular words (which is the same as the number of pirate words)
When you pass an array of arrays, you need to tell the size of each component array. So the heading of your new translate function might be as follows.
  void translate(char word[], char translation[], 
                 char regularWords[][MAX_WORD_SIZE], 
                 char pirateWords[][MAX_WORD_SIZE],
                 int numRegularWords)
Be sure to put the correct physical size for each string in the array, or this will not work correctly.