My file structure is Project data sort
main.cpp code as follows

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include "genlist.cpp"
#include "genstring.cpp"

using namespace std;

int main(int argc, char *argv[])
{
    ifstream in;
    ofstream out;
    int unique=0;
    GenList<string> gList;
    gList.checkFileOpen(in,out);
    gList.populateNUnique(in);
    gList.sort(1);
    gList.output();
    in.close();
    system("PAUSE");
    return EXIT_SUCCESS;
}

and genlist.cpp as follows

#ifndef _GENLIST
#define _GENLIST
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;

template <class T>
class GenList{
      public:
      GenList();
      void sort(int hToL);
      void checkFileOpen(ifstream& in);
      void checkFileOpen(ifstream& in, ofstream& out);
      void populateNUnique(ifstream& in);
      void populateUnique(ifstream& in, string str);
      void output();
      void output(ofstream& out);
      int getNUnique();

      private:
      void eliminateDuplicate();
      int nUniqueCount,uniqueCount;
      vector<T> list;
      vector<int> count;
  
};
      template <class T>
      GenList<T>::GenList<T>(){
      nUniqueCount=0;
      uniqueCount=0;                         
      }
      template <class T>
      void GenList<T>::sort(int hToL){
           switch(hToL){
           case 1:  //High to low
                stable_sort(list.begin(), list.end());
                break;
           case 2: //Low to high
                stable_sort(list.begin(), list.end());
                reverse(list.begin(), list.end());
                break;
           }
           eliminateDuplicate();
                  
      }
      template <class T>
      int GenList<T>::getNUnique(){
          return nUniqueCount;
      }
      template <>
      void GenList<string>::populateNUnique (ifstream& in){
           char next;
           string str, temp; 
           stringstream ss;
           int sCounter=0, caps=1;//; //scounter counts spaces in program, caps makes sure first letter only is capatalized
           while (!in.eof()){
                 in.get(next);
                 if ((next >=65 && next <=90) || (next>= 97 && next <=122)){    //check if character is a letter caps or not
                           if ((next >=97 && next <= 122) && caps==1){ //check if letter is not capatalized if not capatalize it 
                                     next-=32;
                                     }
                           if ((next>=65 && next<=90) && caps==0){ //check if proceeding characters are capatalized if so make them lowercase
                                     next+=32;
                                     }
                           caps=0;
                           
                           ss << next; //output char to streamstream
                           sCounter=0;
                 } else if (sCounter<1){ // if junk input create a space and put it into string stream ::This line guards agains multiple space insertion into string stream.
                           next=' ';
                           sCounter++;
                           ss<< next;
                           ss>>str;
                           list.push_back(str);
                           caps=1;
                           nUniqueCount++;
                 }
           }
           if ((next >=65 && next <=90) || (next>= 97 && next <=122)){ //Also insures that last word is counted in the array.
               next=' ';                                               
               ss<< next;
               ss>>str;
               list.push_back(str);
               temp=list.back();                //Protect against a bug 
               temp.erase((temp.length()-1),1); //that adds double character
               list.back()=temp;                // to last word in vector.
               nUniqueCount++;
           }
      }

      template <class T>
      void GenList<T>::populateNUnique (ifstream& in){
           char next;
           string str, temp; 
           stringstream ss;
           int sCounter=0, caps=1;//; //scounter counts spaces in program, caps makes sure first letter only is capatalized
           while (!in.eof()){
                 in.get(next);
                 if ((next >=65 && next <=90) || (next>= 97 && next <=122)){    //check if character is a letter caps or not
                           if ((next >=97 && next <= 122) && caps==1){ //check if letter is not capatalized if not capatalize it 
                                     next-=32;
                                     }
                           if ((next>=65 && next<=90) && caps==0){ //check if proceeding characters are capatalized if so make them lowercase
                                     next+=32;
                                     }
                           caps=0;
                           
                           ss << next; //output char to streamstream
                           sCounter=0;
                 } else if (sCounter<1){ // if junk input create a space and put it into string stream ::This line guards agains multiple space insertion into string stream.
                           next=' ';
                           sCounter++;
                           ss<< next;
                           ss>>str;
                           list.push_back(str);
                           caps=1;
                           nUniqueCount++;
                 }
           }
           if ((next >=65 && next <=90) || (next>= 97 && next <=122)){ //Also insures that last word is counted in the array.
               next=' ';                                               
               ss<< next;
               ss>>str;
               list.push_back(str);
               temp=list.back();                //Protect against a bug 
               temp.erase((temp.length()-1),1); //that adds double character
               list.back()=temp;                // to last word in vector.
               nUniqueCount++;
           }
      }

      template <class T>
      void GenList<T>::populateUnique (ifstream& in, string uKey){
           char next;
           string str; 
           stringstream ss;
           int sCounter=0; //scounter counts spaces in program, caps makes sure first letter only is capatalized
           while (!in.eof()){
                 in.get(next);
                 if ((next >=65 && next <=90) || (next>= 97 && next <=122)){    //check if character is a letter caps or not
                           ss << next; //output char to streamstream
                           sCounter=0;
                 } else if (sCounter<1){ // if junk input create a space and put it into string stream ::This line guards agains multiple space insertion into string stream.
                           next=' ';
                           sCounter++;
                           ss<< next;
                           ss>>str;
                           if (uKey == str){
                                    list.push_back(str);
                                    uniqueCount++;
                           }
                 }
           }
      }
      template <class T>
      void GenList<T>::output (){
             for (int i=0;i<list.size();i++){
                     cout << list[i]<< " Word Count:" << count[i] << endl;//count[i] <<endl;
                     }  
           }
      template <class T>
      void GenList<T>::output (ofstream& out){}
      
      template <class T>
      void GenList<T>::checkFileOpen(ifstream& in, ofstream& out){
           	string inputfilename, outputfilename,bad="Your file failed to open";
	        while (!in.is_open()) {
                  in.clear();
		          cout << "Input filename: ";
		          getline (cin, inputfilename);
		          try{
		              in.open(inputfilename.c_str());
		              if (in.fail())
		                 throw (bad);
                  } 
                  catch(string bad){               
                      cout << bad << endl;
                  }
            }
	        while (!out.is_open()) {
		          cout << "Output filename: ";
                  getline (cin, outputfilename);
                  out.open(outputfilename.c_str());
	        }	    
      }
      template <class T>
      void GenList<T>::checkFileOpen(ifstream& in){
           	string inputfilename, outputfilename,bad="Your file failed to open";
	        while (!in.is_open()) {
                  in.clear();
		          cout << "Input filename: ";
		          getline (cin, inputfilename);
		          try{
		              in.open(inputfilename.c_str());
		              if (in.fail())
		                 throw (bad);
                  } 
                  catch(string bad){               
                      cout << bad << endl;
                  }
            }	    
      }
      template <class T>
      void GenList<T>::eliminateDuplicate(){
           int temp=0, c=1;
           for (int i=1; i < list.size(); i++){
               if (list[temp]==list[i]){
                  list.erase(list.begin()+i);
                  c++;  //counts how many words there are.
                  i--;  //decrements i to account for the automatic shift back of the erasing of the vector.
                  } else {
                    temp=i;
                    count.push_back(c);
                    c=1;
                    }
           }
           count.push_back(c); //Accounts for last word
      }
#endif

When i compile i get the following errors.
multiple definition of `GenList<std::string>::populateNUnique(std::basic_ifstream<char, std::char_traits<char> >&)'
first defined here
ld returned 1 exit status
"FILE PATH HERE"\Makefile.win [Build Error] ["Data] Error 1
I am using Dev c++ to compile the code. If you didn't get it from the code, i am trying to specialize the string data type for the populateNUnique function.
Thanks in advance.
I'm also new to the forum, so go easy on me in terms of where i posted and such.

Recommended Answers

All 3 Replies

Lines 55 and 96 of this post. Which one is wrong?

[edit]
Wait. Let me look again. I missed the specialization comment.

I found the solution just in case anyone is staring at this thread wondering the same thing about there template. The template is supposed to be a .h(header) rather than a .cpp.

I found the solution just in case anyone is staring at this thread wondering the same thing about there template. The template is supposed to be a .h(header) rather than a .cpp.

Yes thats, a known fact. The up coming C++0x is going to fix this.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.