#include #include #include #include #include #include #include #include #define MAX_LINE_LENGTH 70 class Third_word_node; class Second_word_node; class Random { public: unsigned long Next(); void Set_Seed(int i) { Seed = i; } private: unsigned long Seed; }; class First_word_node { friend class Word_tree; friend class Interface; public: First_word_node * Next() { return next; } Second_word_node * In() { return list; } private: First_word_node * next = NULL; Second_word_node * list = NULL; char Word[50]; }; class Second_word_node { friend class Word_tree; friend class Interface; public: Second_word_node * Next() { return next; } Third_word_node * In() { return list; } private: Second_word_node * next = NULL; Third_word_node * list = NULL; char Word[50]; }; class Third_word_node { friend class Word_tree; friend class Interface; public: Third_word_node * Next() { return next; } private: char Word[50]; int count; Third_word_node * next; }; class Word_tree { friend class Interface; public: void Add_entry(char * first_word, char * second_word, char * third_word); void Reset() { Top = NULL; } char * Get_word(char * first_word, char * second_word); private: First_word_node * Top = NULL; }; class Parser { public: void Parse_Input(ifstream * infile, Word_tree * tree); private: char first_word[50]; char second_word[50]; char third_word[50]; }; class Interface { public: void Open_list(); void New_list(); void Save_list(); void Read_into_list(); void Print_tree(); void Create_text(); void Quit_out(); void Get_command(); private: void Print_outfile(); void Parse_infile(); Parser p; Word_tree tree; ifstream * infile; ofstream * outfile; int save_flag; }; Random r; void Interface::Open_list() { char buffer[50]; cout << endl << "Enter filename to open: "; cin >> buffer; ifstream temp(buffer); if(!temp) { cout << "Can't open " << buffer << "." << endl; return; } infile = &temp; Parse_infile(); } void Interface::New_list() { char buffer; if(save_flag == 1) { save_flag = 0; cout << endl << "Current word list hasn't been saved. Save now? (Y/N) "; cin >> buffer; if(!(buffer == 'N') && !(buffer == 'n')) Save_list(); } tree.Reset(); cout << "New word list started." << endl; } void Interface::Save_list() { char buffer[50]; save_flag = 0; cout << "Enter filename to save to: "; cin >> buffer; ofstream temp(buffer); if(!temp) { cout << "Can't open " << buffer << "." << endl; return; } outfile = &temp; Print_outfile(); } void Interface::Read_into_list() { char buffer[50]; cout << "Enter name of text file to read: "; cin >> buffer; ifstream temp(buffer); if(!temp) { cout << "Can't open " << buffer << "." << endl; return; } infile = &temp; p.Parse_Input(infile, &tree); save_flag = 1; } void Interface::Create_text() { char buffer[50]; char x; char first_word[50] = "*go*\0"; char second_word[50] = "*go*\0"; int line_length = 0; cout << "Enter name of output file: "; cin >> buffer; ofstream temp(buffer); if(!temp) { cout << "Can't open " << buffer << "." << endl; return; } outfile = &temp; while(1) { strcpy(buffer, tree.Get_word(first_word, second_word)); if(!strcmp(buffer, "*doh*\0")) break; if(!strcmp(buffer, "*newline*")) strcpy(buffer, "\n"); *outfile << buffer << " "; line_length += strlen(buffer) + 1; if(line_length >= MAX_LINE_LENGTH) { *outfile << "\n"; line_length = 0; } strcpy(first_word, second_word); strcpy(second_word, buffer); } } void Interface::Quit_out() { char buffer; if(save_flag == 1) { cout << "The current word_list has not been saved. Save now? (Y/N) "; cin >> buffer; if(!(buffer == 'N') && !(buffer == 'n')) Save_list(); exit(1); } exit(1); } void Interface::Print_outfile() { First_word_node * temp; Second_word_node * temp2; Third_word_node * temp3; temp = tree.Top; while(temp != NULL) { *outfile << temp->Word << "\t"; temp2 = temp->In(); while(temp2 != NULL) { *outfile << temp2->Word << "\t"; temp3 = temp2->In(); while(temp3 != NULL) { *outfile << temp3->Word << "\t" << temp3->count << "\t"; temp3 = temp3->Next(); } *outfile << "*end*" << "\t"; temp2 = temp2->Next(); } *outfile << "*end*" << "\t"; temp = temp->Next(); } *outfile << "*end*" << endl; } void Interface::Parse_infile() { First_word_node * temp; Second_word_node * temp2; Third_word_node * temp3; char First_word[50]; char Second_word[50]; char Third_word[50]; int i, new_count; char buffer; while(1) { if(infile->eof()) break; while((infile->get(buffer)) && (buffer == '\t')); First_word[0] = buffer; i = 1; while((infile->get(buffer)) && (buffer != '\t')) { First_word[i] = buffer; i++; } First_word[i] = '\0'; if((First_word[0] == '*') && (First_word[1] == 'e') && (First_word[2] == 'n') && (First_word[3] == 'd') && (First_word[4] == '*')) break; temp = new First_word_node; strcpy(temp->Word, First_word); temp->next = NULL; temp->list = NULL; while(1) { while((infile->get(buffer)) && (buffer == '\t')); Second_word[0] = buffer; i = 1; while((infile->get(buffer)) && (buffer != '\t')) { Second_word[i] = buffer; i++; } Second_word[i] = '\0'; if(!strcmp(Second_word, "*end*")) break; temp2 = new Second_word_node; strcpy(temp2->Word, Second_word); temp2->next = NULL; temp2->list = NULL; while(1) { while((infile->get(buffer)) && (buffer == '\t')); Third_word[0] = buffer; i = 1; while((infile->get(buffer)) && (buffer != '\t')) { Third_word[i] = buffer; i++; } Third_word[i] = '\0'; if(!strcmp(Third_word, "*end*")) break; *infile >> new_count; temp3 = new Third_word_node; strcpy(temp3->Word, Third_word); temp3->count = new_count; temp3->next = temp2->In(); temp2->list = temp3; } temp2->next = temp->In(); temp->list = temp2; } temp->next = tree.Top; tree.Top = temp; } } void Interface::Get_command() { char buffer; cout << "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl; cout << "| Please enter one of the following commands. |" << endl; cout << "+---------------------------------------------------------------+" << endl; cout << "| O -- Open an existing word list. |" << endl; cout << "+ N -- Create a new word list. +" << endl; cout << "| S -- Save current word list. |" << endl; cout << "+ R -- Read a text file into the current word list. +" << endl; cout << "| P -- Print current word list to the screen. |" << endl; cout << "+ G -- Create a new text file based on the current word list. +" << endl; cout << "| Q -- Quit |" << endl; cout << "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl; cout << "Your choice? "; cin >> buffer; switch(toupper(buffer)) { case 'O': { Open_list(); break; } case 'N': { New_list(); break; } case 'S': { Save_list(); break; } case 'R': { Read_into_list(); break; } case 'P': { Print_tree(); break; } case 'G': { Create_text(); break; } case 'Q': { Quit_out(); break; } default : { cout << endl << "No such command. Try again." << endl; break; } } } char * Word_tree::Get_word(char * first_word, char * second_word) { First_word_node * temp; Second_word_node * temp2; Third_word_node * temp3; long x,y; temp = Top; if(!strcmp(first_word, "\n")) strcpy(first_word, "*newline*"); if(!strcmp(second_word, "\n")) strcpy(second_word, "*newline*"); while(1) { if(temp == NULL) { return "*doh*\0"; } else if(strcmp(temp->Word, first_word)) temp = temp->Next(); else break; } temp2 = temp->In(); while(1) { if(temp2 == NULL) { return "*doh*\0"; } else if(strcmp(temp2->Word, second_word)) temp2 = temp2->Next(); else break; } temp3 = temp2->In(); x = 0; while(temp3 != NULL) { x += temp3->count; temp3 = temp3->Next(); } y = r.Next() % x; temp3 = temp2->In(); if(temp3 == NULL) cout << "Strange..." << endl; while(y > 0) { if(temp3 == NULL) { cout << "Ran out of words. Hmm." << endl; return "*doh*\0"; } y -= temp3->count; if(temp3->next == NULL) break; temp3 = temp3->Next(); } return temp3->Word; } unsigned long Random::Next() { long A = 48271L; long M = 2147483647L; long Q = M / A; long R = M % A; long tempseed = A * (Seed % Q) - R * (Seed / Q); if(tempseed >= 0) Seed = tempseed; else Seed = tempseed + M; return Seed; } void Interface::Print_tree() { First_word_node * temp; Second_word_node * temp2; Third_word_node * temp3; cout << "The word_tree is as follows..." << endl; temp = tree.Top; while(temp != NULL) { cout << "First Word: " << temp->Word << endl; temp2 = temp->In(); while(temp2 != NULL) { cout << "\tSecond Word: " << temp2->Word << endl; temp3 = temp2->In(); while(temp3 != NULL) { cout << "\t\tThird Word: " << temp3->Word << " : " << temp3->count << endl; temp3 = temp3->Next(); } temp2 = temp2->Next(); } temp = temp->Next(); } } void Word_tree::Add_entry(char * first_word, char * second_word, char * third_word) { First_word_node * temp = Top; Second_word_node * temp2 = NULL; Third_word_node * temp3 = NULL; while(1) { if(temp == NULL) { temp = new First_word_node; strcpy(temp->Word, first_word); temp->next = Top; Top = temp; temp->list = NULL; } else if(strcmp(first_word, temp->Word)) temp = temp->Next(); else { break; } } temp2 = temp->In(); while(1) { if(temp2 == NULL) { temp2 = new Second_word_node; strcpy(temp2->Word, second_word); temp2->next = temp->list; temp->list = temp2; temp2->list = NULL; } else if(strcmp(second_word, temp2->Word)) temp2 = temp2->Next(); else { break; } } temp3 = temp2->In(); while(1) { if(temp3 == NULL) { temp3 = new Third_word_node; strcpy(temp3->Word, third_word); temp3->next = temp2->list; temp2->list = temp3; temp3->count = 0; } else if(strcmp(third_word, temp3->Word)) temp3 = temp3->Next(); else { temp3->count++; break; } } } void Parser::Parse_Input(ifstream * infile, Word_tree * tree) { char buffer; int i = 0; first_word[0] = second_word[0] = '*'; first_word[1] = second_word[1] = 'g'; first_word[2] = second_word[2] = 'o'; first_word[3] = second_word[3] = '*'; first_word[4] = second_word[4] = '\0'; while(1) { i = 0; while((infile->get(buffer)) && ((buffer == ' ') || (buffer == '\n') || (buffer == '\t'))); third_word[0] = buffer; i = 1; while((infile->get(buffer)) && (!infile->eof()) && ((buffer != '\n') && (buffer != ' ') && (buffer != '\t'))) { third_word[i] = buffer; i++; } /* Uncomment the following lines to include newlines in word lists if(buffer == '\n') { infile.putback(' '); infile.putback('\n'); } */ third_word[i] = '\0'; if(!strcmp(third_word, "\n")) strcpy(third_word, "*newline*"); tree->Add_entry(first_word, second_word, third_word); for(i=0; i<50; i++) first_word[i] = second_word[i]; for(i=0; i<50; i++) second_word[i] = third_word[i]; if(infile->eof()) break; } cout << "Done parsing." << endl; } void main() { Interface i; cout << "Jason's Poetry Imitator, v0.1" << endl; r.Set_Seed(getpid()); while(1) i.Get_command(); }