Wow... well this project is finally done. Though it still isn't really, but I'll get to that in a bit....
This project was simply awful. It took me two days to find out why my words weren't printing when I looked up a word to find it's links... low and behold it was because I forgot to put a cout statement there! This is just one example of a whole hosts of simple mistakes compiled with really complex ones that made coding this lil program a living hell. Even now as I'm typing this I still have a headache... so after I post this I'm going to go lie down, but first I wanted to show you what lil bit I did accomplish.
WordLinker v.0.5
It does work. Well it does what it's supposed to do. That is it adds words to the text file... essentially linking them together. This parts works pretty well. There are probably still a few errors, but I haven't found them yet.
Anywho... there is one problem. It only allow you to look up one word, and then it deletes the first letter of your word for every next word you enter... yeh I know beats me too o_O? Anyway here... its quite a bit of code:
Code:
#include <iostream>
#include <fstream>
#include <string>
#define WORD_SLOTS 5000
using namespace std;
bool initialize();
void save();
void start();
void linkWords();
int getWordSlot(char* str);
bool wordExists(char* str);
void findLinks();
class Word
{
int maxlinks;
char wordname[50];
char* links;
int linkcount;
public:
Word(char str[]){strcpy(wordname, str);}
Word(){
maxlinks = 1000;
links = new char[maxlinks];
for(int i = 0; i < maxlinks; i++)links[i] = '\0';
strcpy(wordname, "");
linkcount = 0;
}
void newWord(char* str)
{
strcpy(wordname,str);
}
char* getWord(){return wordname;}
void addDirLink(char* str)
{
if(linkcount>0)
{
links[linkcount] = ' ';
linkcount++;
}
char* temp = new char[1000];
strcpy(temp, str);
//cout<<"temp"<<temp<<endl;
for(int i = 0; temp[i]; i++)
{
links[linkcount] = temp[i];
linkcount++;
}
}
char* getLinks()
{
return links;
}
};
//GLOBAL VARIABLES
Word *word[WORD_SLOTS];
int main()
{
for(int i = 0; i < WORD_SLOTS; i++){word[i] = new Word();}
if(initialize())start();
else return 1;
}
bool initialize()
{
int wordnum = 0;
fstream log("log.txt", ios::in | ios::out);
if(!log){cout << "ERROR. Loading, or creating new library...\n"; return false;}
else cout << "Loading Library...\n";
char p[1000];
while(!log.eof())
{
log.getline(p, sizeof p);
wordnum = getWordSlot(p);
log.getline(p, sizeof p);
if(log.eof()) break;
word[wordnum]->addDirLink(p);
}
log.close();
return true;
}
void start()
{
char ch;
while(true)
{
system("cls");
cout << "Welcome to WordLinker v.0.5\n";
cout << "Menu:\n";
cout << "i. Instructions\n";
cout << "r. Run Linker\n";
cout << "l. Search for links\n";
cout << "s. to show all words\n";
cout << "q. to quit";
cout << endl;
cin >> ch;
switch(ch | 32)
{
case 'i':
// instruction crap...
system("cls");
cout<<"This is WordLinker v.0.5\n"
<<"You can link words together simply by typing in any combination of words on the same line.\n"
<<"Words can either be seperated by a space or by \"\" (quotation marks)\n"
<<"If at any time during the Linking process you would like to return to \n"
<<"the main menu you can do so by typing *menu.\n"
<<"Some other key words are: \n"<<endl
<<"*save -> which will save all of your current links to file.\n"
<<"I reccomend\n you do this after every session otherwise all\n"
<<"the work from the previous session will be lost.\n"<<endl
<<"NOTE: quiting will exit out of WordLinker, but will not automatically save your progress.\n"<<endl;
system("pause");
break;
case 'r':
linkWords();
break;
case 'l':
findLinks();
break;
case 's':
for(int i = 0; i < WORD_SLOTS; i++)
{
if(strcmp(word[i]->getWord(), ""))
{
cout<< word[i]->getWord()<<endl;
cout<<"links to this word are: ";
}
if(strcmp(word[i]->getLinks(), "")) cout<< word[i]->getLinks()<<endl;
}
system("pause");
break;
case 'q':
return;
default:
cout <<"Please choose either \'r\' ro run Wordlinker or \'i\' for instruction as to how the linker works\n";
cin.get();
cin.get();
system("cls");
break;
}
}
}
void linkWords()
{
//Checks for key words NOT important
char wordbuf[1000] = "";
cout<<"Enter words: \n";
cin.ignore();
while(true)
{
cin.getline(wordbuf, sizeof wordbuf);
if(0 == strcmp(wordbuf,"*save")){cout<<"saving...\n"<<endl; save();}
else if(0 == strcmp(wordbuf,"*menu"))return;
else{
//INITIALIZING SOME VARIABLES
int wordnum = 0;
//an array of char*
char* p[50];
for(int i = 0; i < 50; i++)
p[i] = new char[50];
//an important int that keeps track of the number of words in the line
int words = 0;
//a temporary string for tokenizing
char* init_str = new char[50];
strcpy(init_str, wordbuf);
//____________________THE MAIN PART OF THE LINKER_____________________
//PART 1: TOKENIZER
char* temp = strtok(init_str, " \"");
while(temp != NULL)
{
//get a word slot int the global Word array
wordnum = getWordSlot(temp);
cout<<temp<<endl;
strcpy(p[words], temp);
temp = strtok(NULL, " \"");
words++;
}
//PART 2: LINKER
while(words > 0)
{
char* temp_str = new char[50];
strcpy(temp_str, wordbuf);
char* temp2 = strtok(temp_str, " \"");
while(temp2 != NULL)
{
if(!strcmp(p[words-1], temp2))
{
temp2 = strtok(NULL," \"");
continue;
}
word[getWordSlot(p[words-1])]->addDirLink(temp2);
cout<<"linked: "<<temp2 <<" to word: " <<p[words - 1] << endl;
temp2 = strtok(NULL," \"");
}
words--;
}
}//The else
}//The while loop
}
int getWordSlot(char* str)
{
if(!strcmp(str,""))return 0;
for(int i=0; i < WORD_SLOTS; i++)
{
if(!strcmp((const char*)word[i]->getWord(), str))
{
//cout<<"found slot for word: "<< str <<endl;
return i;
}
if(!strcmp((const char*)word[i]->getWord(), ""))
{
word[i]->newWord(str);
//cout<<"found slot for new word: " << str <<endl;
return i;
}
}
}
bool wordExists(char* str)
{
//cout<<"This is str: " << str << endl;
if(!strcmp(str,""))return false;
for(int i=0; i < WORD_SLOTS; i++)
{
//if(strcmp(word[i]->getWord(), "")) cout <<"comparing " << word[i]->getWord() << " to " <<str<<endl;
//strcmp returns 0 if there is not difference between words
if(!strcmp(word[i]->getWord(), str))return true;
}
return false;
}
void findLinks()
{
char wordbuf[1000];
system("cls");
cout<<"NOTE: There is currently an error in the linker. You can only look up one word."<<endl;
cout<<"Enter a word to check for any links. Do not us \"\" around word."<<endl;
cin.ignore();
while(true)
{
cin.getline(wordbuf, sizeof wordbuf);
cout<<"before strcmp: " <<wordbuf<<endl;
if(!strcmp(wordbuf,"*menu"))return;
cout<<"after strcmp: " << wordbuf <<endl;
if(wordExists(wordbuf))
{
cout<<wordbuf<<endl;
cout<<"The direct links with this word are: " << word[getWordSlot(wordbuf)]->getLinks()<<endl;
system("pause");
}
else
{
cout<<"Word does not yet exist."<<endl;
cout <<"Try a different word." <<endl;
cout<<wordbuf<<sizeof wordbuf<<endl;
system("pause");
}
cin.ignore();
}
}
void save()
{
cout<<"Inside save functon...\n";
fstream log("log.txt", ios::in | ios::out | ios::trunc);
if(!log)
{
cout<<"Error opening save file.\n";
return;
}
else
{
cout<<"opened log.txt sucessfully\n";
for(int i = 0; i < 3; i++)cout<<word[i]->getWord()<<endl <<word[i]->getLinks()<<endl;
for(int i=0; strcmp(word[i]->getWord(), ""); i++)
{
log << word[i]->getWord();
cout<< "added word: "<< word[i]->getWord() <<" in slot: " << i <<" to log.txt" <<endl;
log << endl;
log << word[i]->getLinks();
log << endl;
cout<<"added wordlinks: " << word[i]->getLinks()<< " to log.txt"<<endl;
}
log.close();
}
return;
}
I annotated the linkWords function because it works so well, however the other functions should be pretty easy to understand as well. Hope this help someone. Oh and I would really appreciate it if anyone could figure out why the first letter is concatenated when finding links. Thanks