Today's program code follows these comments. /* Files as Parameters to Functions: It makes sense that writing or outputting to an ofstream changes that ofstream in some way: the file is actually modified. Inputting from an ifstream also changes it, bit in a less obvious way. An ifstream represents a program's connection to a disc file. Although the file itself isn't changed, the ifstream must remember how much has been read, otherwise you would keep getting the very first data item over and over again. Therefore, when an ifstream or an ofstream is passed to a function as a parameter, it must be a reference parameter, as seen in read_word_list below. The Size of an Array: When an array is created like this: string list[100]; int ages[100]; the number 100 says how many items are in the array. Items in an array (in C++) are always counted from zero, so the 100 items are A[0], A[1], A[2], ..., up to A[99]. There is no such thing as A[100]. If you want A[100] to exist, you must use a size of 101 when creating the array. When an Array is passed to a Function as a Parameter: 1. C++ will automatically treat it as a reference parameter. You do not need to type the &. In fact, you must not type the &, as it would cause an error. 2. In its declaration, the name of the array parameter is followed by an empty pair of square brackets []. Do not put the array's size in there. Any size you do type inside the square brackets will be ignored. If it is wrong, you will not be informed. When an array is created, as in the second line of main, you must specify the size, otherwise C++ would have no clue how much memory to set aside for it. When a function receives an array parameter, it is always an array that already exists. Whatever its size is, you're stuck with that. Functions that accept array parameters will happily accept arrays of any size. 3. If a function needs to know how big an array is (and it usually does need to know), it must be told. The size should be passed in as an additional int parameter. See read_word_list and find_word_in_list below. Functions that create Arrays. It is not possible in C++ for a function to return an array as its result. Strings are a lot like Arrays. 1. A string behaves like an array of individual characters. This little piece of program string pig = "Cat"; cout << pig[0] << " - " << pig[2] << " - " << pig[1]; would print out "C - t - a". 2. But strings are also like structs or objects, they have other things inside them. One of those things is a Function that returns the length of the string, so in that example, pig.length() would be 3. 3. When you access an individual character of a string, C++ treats it as a small int (except when it is printed by cout, as above). This int is the ASCII code for the character. 4. When you type a single character inside single quotes, such as 'A', or '3', C++ treats that as a representation of an int, equal to the character's ASCII code. For example, when 'C' appears in a program, it has exactly the same effect as if 67 had been typed there instead. You can see the ASCII code table here: http://rabbit.eng.miami.edu/info/ascii.html 5. 'A'+1 is 'B', 'B'+1 is 'C', etc. Saying pig[0] = pig[0] + 2, in the above example, would change the string to "Eat". 6. As all the capital letters are coded together in a contiguous run, and so are all the little letters, some operations are easy. If c is a char: (c>='A' && c<='Z') checks to see if c is a capital letter. c+('a'-'A') converts c from a capital letter to the equivalent little letter. If c wasn't a capital to start with, the result would be a mess. c+('A'-'a') converts little letters to the equivalent capitals. */ #include #include #include using namespace std; string uncapitalise(string s) { int size = s.length(); int pos = 0; while (pos < size) { if (s[pos]>='A' && s[pos]<='Z') s[pos] = s[pos]+('a'-'A'); pos = pos+1; } return s; } int read_word_list(ifstream & win, string arr[], int maxsize) { int count = 0; while (count < maxsize) { string word; win >> word; if (win.fail()) break; arr[count] = uncapitalise(word); count = count + 1; } return count; } bool find_word_in_list(string word, string wordlist[], int numwords) { int i = 0; while (i < numwords) { if (wordlist[i] == word) return true; i = i+1; } return false; } void main() { const int array_size = 120000; string wordlist[array_size]; ifstream win("/home/www/dics/knuthus.txt"); if (win.fail()) { cout << "Couldn't open the word list\n"; exit(1); } int numwords = read_word_list(win, wordlist, array_size); win.close(); cout << numwords << " words successfully read\n"; ifstream story("story.txt"); if (story.fail()) { cout << "Couldn't open the file\n"; exit(1); } while (true) { string word; story >> word; if (story.fail()) break; bool matched = find_word_in_list(uncapitalise(word), wordlist, numwords); if (!matched) cout << word << " is no good\n"; } story.close(); cout << "All done\n"; }