2011-09-14 119 views
2

我剛剛寫了一個簡單的遊戲(如果你有興趣,每個玩家都應該說一個字,以他的對手說的這個詞的最後一個字母開頭) 它不會編譯下面的輸出:「undefined reference」error with g ++

[email protected]:~/projects/dict$ g++ wordgame.cc 
/tmp/ccIjadX8.o: In function `main': 
wordgame.cc:(.text+0x90b): undefined reference to `WGdict::~WGdict()' 
wordgame.cc:(.text+0x92e): undefined reference to `WGdict::~WGdict()' 
collect2: ld returned 1 exit status 

的代碼:

dict.h:

#include <map> 
#include <string> 
#include <fstream> 
#include <set> 
#include <vector> 

#define ft first 
#define sd second 
#define MCMSB map<char,map<string,bool> > 
#define MSB map<string,bool> 
#define PSB pair<string,bool> 

using std::map; 
using std::vector; 
using std::pair; 
using std::set; 
using std::ifstream; 
using std::ofstream; 
using std::string; 



class WGdict{ 
    private: 

    MCMSB M;//main map 
    bool HasBeenFilled; 

    bool WasUsed(MSB::iterator it){//a small function which checks the "used" bit at the iterator 
    return (*it).sd; 
    } 

string strip(string str){ 
    string::iterator i = str.begin(); 
    char space = ' '; 
    while(*i == space){ 
     i = str.erase(str.begin()); 
    } 
    i = str.end()-1; 
    while(*i == space){ 
     str.erase(i); 
     i = str.end()-1; 
    } 
    return str; 
} 

bool FillFromFile(string filename){return FillFromFile(filename,false);}//default 

bool FillFromFile(string filename, bool PreserveContents){//fills the main map with contents of file 
    ifstream dicfile (filename.c_str());//open file 
    if(dicfile.is_open()&&dicfile.good()){ 
     string str; 
     if(!PreserveContents){ 
      M.clear();//clear map 
     } 
     char c; 
     while(!dicfile.eof()){//get words from file and add them to the map 
      dicfile>>str; 
      str = strip(str); 
      c=str[0]; 
      M[c].insert(PSB(str,false)); 
     } 
     HasBeenFilled = 1; 
     dicfile.close(); 
     return true; 
    } 
    else if (dicfile.is_open()) dicfile.close(); 
    return false; 
} 

bool setbool(string word, bool state , bool flip){// set to STATE (or flip) the "used" bool 
    bool ok = false; 
    MCMSB::iterator it = M.find(word[0]); 
    if(it != M.end()){ 
     MSB::iterator O = it->sd.find(word); 
     if(O != it->sd.end()){ 
      if(!flip) O->sd = state; 
      else O->sd = ! (O->sd); 
      ok=true; 
     } 
    } 
} 

public: 


WGdict(){HasBeenFilled = false;}//default constructor 

~WGdict(){ M.clear(); }//destructor 

WGdict(string fname){//file-opening constructor 
    open(fname); 
} 

bool open(string fname){//open new file with default settings 
    return FillFromFile(fname); 
} 

bool open(string fname,bool pc){//open new file and choose whether to preserve contents 
    return FillFromFile(fname,pc); 
} 

MSB find(char ch){//search the dictionary by first letter 
    MCMSB::iterator it = M.find(ch); 
    MSB results; 
    if (it!=M.end()){ 
     results = (*it).sd; 
    } 
    return results; 
} 

vector<string> find(char ch, bool wu){//search the dictionary by first letter&"used" parameter 
    vector<string> v; 
    MSB search = find(ch); 
    for(MSB::iterator it = search.begin();it!=search.end();it++){ 
     if(WasUsed(it)==wu) v.push_back((*it).ft); 
    } 
} 

set<string> findS(char ch, bool wu){//same as previous, but output is in a set 
    set<string> s; 
    MSB search = find(ch); 
    for(MSB::iterator it = search.begin();it!=search.end();it++){ 
     if(WasUsed(it)==wu) s.insert((*it).ft); 
    } 
} 

void save(string filename){//save a dictionary 
    ofstream of(filename.c_str()); 
    if(of.is_open()&&of.good()){ 
     for(MCMSB::iterator me=M.begin() ; me!=M.end();me++){ 
      for(MSB::iterator i = me->sd.begin(); i != me->sd.end() ; i++){ 
       of<<((*i).ft+"\n").c_str(); 
      } 
     } 
     of.close(); 
    } 
    else if (of.is_open()) of.close(); 
} 

void add(string word){add(word,false);}//add a word to the dictionary 

void add(string word,bool b){ 
    char c = strip(word)[0]; 
    M[c].insert(PSB(word,b)); 
} 

bool flip(string word){return setbool(word,0,1);} 

bool use(string word){return setbool(word,1,0);} 

bool use(string word, bool state){ return setbool(word,state,false);} 

bool exists(string word){ 
    bool ok = false; 
    MCMSB::iterator it = M.find(word[0]); 
    if(it != M.end()){ 
     MSB::iterator O = it->sd.find(word); 
     if(O != it->sd.end()){ 
      ok=true; 
     } 
    } 
} 

bool used(string word){ 
    if(exists(word)){ 
     return M.find(word[0])->sd.find(word)->sd; 
    } 
    return true; 
    } 
}; 

wordgame.cc:

# include "dict.h" 
# include <vector> 
# include <iostream> 
# include <algorithm> 

using namespace std; 

char getlastletter(string str){return str[str.size()-1];} 

char sayword(vector<string> words){ 
random_shuffle (words.begin(), words.end()); 
string theword = (*words.begin()); 
cout<<theword; 
return getlastletter(theword); 
} 

char big(char ch){ 
if('a'<=ch<='z') ch-=32; 
return ch; 
} 

char small(char ch){ 
if('A'<=ch<='Z') ch+=32; 
return ch; 
} 

string small(string str){ 
for(string::iterator it = str.begin();it != str.end();it++){ 
    (*it) = small((*it)); 
} 
} 

string big(string str){ 
for(string::iterator it = str.begin();it != str.end();it++){ 
    (*it) = big((*it)); 
} 
} 


int main(){ 
    WGdict dict; 
vector<string> ws; 
string fnm,word; 
char yourletter = 'a'; 
char myletter; 

while(true){ 
    cout<<"Write the filename of the dictionary:"; 
    cin>>fnm; 
    if(fnm == "[exit]" || dict.open(fnm)) break; 
    else cout<<"It seems that the file \""<<fnm<<"\" does not exist.\n Try again\n\n" ; 
} 
if(fnm == "[exit]") return 0; 
cout<<"Let's play a word game!\n\n"; 


while(true){ 
    cout<<"My turn: "; 
    ws = dict.find(yourletter,false); 
    if(ws.size() == 0){//exit if no more words are available. 
     cout<<"uh oh. It appears that I couldn't find any unused words with this letter. \n But, yet, congratulations! You won! \n bye! \n"; 
     return 0; 
    } 
    myletter = sayword(ws); 
    cout<<"\n"; 
    ws = dict.find(myletter,false); 
    if(ws.size() ==       0){//exit if no more words are available. 
     cout<<"So... I managed to win this game! My dictionary contains no more words beginning with this letter. \n Although I won, you also did well. \n bye! \n See you soon!"; 
     return 0; 
    } 
    cout<<"Your turn:\n"; 
    while(true){ 
     cout<<big(myletter); 
     cin>>word; 
     word = small(word); 
     if (word == "[exit]") return 0; 
     if (word[0] == small(myletter)){ 
      if(dict.exists(word)) { 
       if(!dict.used(word)){ 
        yourletter = getlastletter(word); 
        dict.use(word); 
        break; 
       } 
       else cout<<"this word has already been used \n"; 
      } 
      else cout<<"Sorry, I couldn't find \""<<word<<"\" in my dictionary. \n"; 
     }else cout<<"\""<<word<<"\" does not begin with letter "<<big(myletter)<<"! \n"; 
     cout<<"try again! \n"; 
    } 
} 
} 

我既不明白是什麼原因導致錯誤,也不知道如何解決,所以請告訴我我做錯了什麼。

+0

這對我有用。 –

+0

適合我。 :-) –

+0

爲什麼它不適合我,那麼? – totosus

回答

3

刪除目錄中的編譯/目標文件並重新編譯 - 代碼工作得很好,你可能只需要make-clean。

+1

PS:作品很棒,我的意思是編譯:)我沒有走得更遠。 –

+0

謝謝!它編譯。但是現在程序崩潰了「分段錯誤」。去找出這意味着什麼。 – totosus

+0

沒問題,有時會發生。當您獲得大型應用程序並開始使用具有大型構建文件的鏈接庫時,情況會變得更糟:p –