#include #include #include #include #include #include // program limitations const int max_line_length = 100, max_words = 200, max_word_length = 40, max_filename_length = 60; struct word_record { char word [max_word_length + 1]; int counter; }; void pause (void) { cout << "Hit any key to continue...\n"; getch (); } bool get_next_word (const char string[], int &start, char word[]) { int i; // advance until we hit a letter, a number, or the terminator while (!isalnum(string[start]) && (string[start] != '\0')) { start++; } if (string[start] == '\0') { return false; } // copy until we get something that isn't alphanumeric i = 0; do { word[i++] = string[start++]; } while (isalnum(string[start])); word[i] = '\0'; // terminate word return true; } void update_word_list (char word[], word_record word_list[], int &word_count) { int i; // see if the word is already on our list for (i = 0; i < word_count; i++) { if (stricmp(word_list[i].word, word) == 0) { // word exist on list - all we need do is update the count word_list[i].counter++; return; } } if (word_count == max_words) { // no more room - report the problem and ignore the word cout << "Unable to add <" << word << "> to the word list (list full).\n"; return; } strcpy (word_list[word_count].word, word); word_list[word_count++].counter = 1; // one occurrance so far } void sort_word_list (word_record word_list[], int word_count) { word_record temp; int i, j; for (i = 0; i < word_count - 1; i++) { for (j = i + 1; j < word_count; j++) { if (stricmp(word_list[i].word, word_list[j].word) > 0) { temp = word_list[i]; word_list[i] = word_list[j]; word_list[j] = temp; } } } } void output_word_record (ostream &os, const word_record &record) { os << setw(3) << record.counter << " : " << record.word << endl; } void main (void) { char line [max_line_length + 1]; // allow for terminator ifstream fin; ofstream fout; char filename[max_filename_length + 1], word[max_word_length + 1]; int word_count = 0, // number of different words total_words = 0, // total number of words start, i; word_record word_list[max_words]; cout << "Please enter the name of the input file: "; cin >> setw(max_filename_length + 1) >> filename; fin.open (filename); if (fin.fail()) { cout << "Unable to open file " << filename << ".\n"; pause (); return; } cout << "PLease enter the name of the output file: "; cin >> setw(max_filename_length + 1) >> filename; fout.open (filename); for (;;) { fin.getline (line, max_line_length + 1); if (fin.fail()) { // read didn't work for some reason if (!fin.eof()) { // some kind of error occurred // warn user that an problem occurred cout << "An error occuring in reading the input file.\n"; // we could abort here, but it makes to more sense to // continue and output what we've got (i.e. to treat the // error as a kind of end of file condition) } break; } // process all of the words in the line we've just read start = 0; for (;;) { if (!get_next_word (line, start, word)) { break; // no more words to process } // start has now been updated (by the function) so that it's // all ready for the extraction of the next word update_word_list (word, word_list, word_count); total_words++; } } sort_word_list (word_list, word_count); // write results to the output file fout << "The file processed contains " << total_words << " total words.\n" << "There are " << word_count << " different words.\n"; for (i = 0; i < word_count; i++) { output_word_record (fout, word_list[i]); } cout << "Results successfully written to file.\n"; pause (); }