2014-10-25 7 views
0

Итак, я уже писал свой код, и я не лучший кодер в мире. я все еще изучаю и считаю себя новичком. im писать лексический анализ для класса понятий в C++. Ive пробовал решения ive, видимые на таких сайтах, как использование extern в файле заголовка и использование const в файлах cpp, но замечание works.when я включаю свой заголовочный файл в 2 отдельных файла .cpp, я получаю эту ошибку для всех ints в заголовочном файле:Ошибка LNK2005, уже определенная в main.obj

tokens.obj: ошибка LNK2005: (? @@ 3HA КОНЕЦ) "ИНТ END" уже определено в main.obj

заголовочного файла =

#include <string.h> 
#include <map> 

using namespace std; 

extern int lANGLE=1, rANGLE=2,iD=3, eQ=4, sLASH=5, qSTRING=6, oTHER=7, eND=8, tEXT=9; 

map <int, int> counter; 

extern int getToken(istream *br, string& lexeme); 

token.cpp (заявляя, что делает getToken)

#include "suffix.h" 
#include <iostream> 
#include <fstream> 
#include <map> 
#include <cctype> 

bool slash = false; 
bool text = false; 
bool quote = false; 
bool id = false; 
bool equ = false; 
bool other = false; 
bool qstring = false; 
char prev=NULL; 

int getToken(istream *in, string& lexeme) 
{ 
    char c; 
    char prev; 
    lexeme=""; 

    int intSlash = 0; 

    int intText = 0; 

    int intQuote = 0; 

    int intId = 0; 

    int intEqual = 0; 

    int intOther = 0; 

    int intQstring = 0; 

    int langlec = 0; 
    int intLangle = 0; 

    int ranglec = 0; 
    int intRangle = 0; 

    if (in->eof()) 
     return eND; 

    while (in->get(c)) 
    { 
     switch (c) 
     { 
      case '/' : 
       if (quote == false && langlec > 0) 
       { 
       slash = true; 
       intSlash++; 
       return 5; 
       } 
       break; 

      case '=' : 
       if (quote == false && langlec > 0) 
       { 
       equ = true; 
       intEqual++; 
       return 4; 
       } 
       break; 

      case '<' : 

       if ( prev != ' ' && langlec == 0) 
        {intText++ ; 
       return 9;} 

       if (quote == false) 
       { 
        langleC++; 
        intLangle ++; 
        id = true; 
        return 1; 
       } 


       break; 


      case '>' : 

       if (quote != true) 
       { 
        ranglec++; 
        intRangle++; 
        return 2; 

        if (langlec > 0) 
        { 
         langlec--; 
         id = false; 
        } 
       } 
       break; 

      case '"' : 
       if (langlec > 0 && quote == true) 
       { 
        quote = false; 
        id = true; 
        intQstring ++; 
        intOther--; 
        return 6; 
       } 
       else if (langlec > 0) 
       { 
        intOther++; 
        quote = true; 
        return 7; 
       } 



       break; 

      case ' ': 
       if (prev != ' ' && prev != '<' && prev != '>' && quote == false){ 
        if (langlec == 0){ 
         intText++; 
         return 9; 
        } 
       } 
        else if (prev != '/' && prev != '=') 
         {intId++; 
         return 3; 
        } 

       break; 

      default: 

       if (quote == true) 
        { 
         id = false; 
        } 

       else if (id==true) 
        { 
         intId++; 
         id=false; 
         return 3; 
        } 
       prev=c; 

     } 
    } 
return 0; 
} 

main.cpp

#include <iostream> 
#include <fstream> 
#include <map> 
#include <cctype> 
#include <string> 
#include <algorithm> 
#include "suffix.h" 

using namespace std; 

int 
main(int argc, char *argv[]) 
{ 
istream *br; 
ifstream infile; 
// check args and open the file 
if(argc == 1) 


br = &cin; 
else if(argc != 2) { 
cout<<"THERE IS A FATAL ERROR"<<endl; 
return 1; // print an error msg 
} else { 
infile.open(argv[1]); 
if(infile.is_open()) 
br = &infile; 
else { 
cout << argv[1] << " can't be opened" << endl; 
return 1; 

} 
} 
string tokens=""; 
int typeOfToken; 

while(true){ 
    typeOfToken=getToken(br,tokens); 
    if (counter.count(typeOfToken)) 
     counter[typeOfToken]+=1; 
    else 
     counter[typeOfToken]=1; 

    if(typeOfToken==8) 
     break; 
} 
cout<<"total token count: "<<endl; 
if (counter[1]!=0) 
    cout<<"LANGLE: "<<counter[1]<<endl; 
if (counter[2]!=0) 
    cout<<"RANGLE: "<<counter[2]<<endl; 
if (counter[9]!=0) 
    cout<<"TEXT: "<<counter[9]<<endl; 
if (counter[3]!=0) 
    cout<<"ID: "<<counter[3]<<endl; 
if (counter[4]!=0) 
    cout<<"EQ: "<<counter[4]<<endl; 
if (counter[5]!=0) 
    cout<<"SLASH: "<<counter[5]<<endl; 
if (counter[6]!=0) 
    cout<<"QSTRING: "<<counter[6]<<endl; 
if (counter[7]!=0) 
    cout<<"OTHER: "<<counter[7]<<endl; 

return 0; 
} 
+1

Вы его определения в заголовке, поэтому он получает определенный в обоих файлах. Вам нужно * объявить * его в заголовке и * define * его только в одном из них. –

+0

Не используйте код самостоятельно. –

ответ

0
extern int lANGLE=1, ... eND=8 

Это должно быть extern декларация, но из-за явной инициализации на самом деле это определение. Таким образом, вы определяете все эти переменные в нескольких единицах перевода, что приводит к нарушению One Definition Rule.

Когда вы это исправить, вы будете иметь те же проблемы с map <int, int> counter;

Что вы должны сделать, это ответить себе на вопрос, почему вы должны объявить все это в файле заголовка. map <int, int> counter; используется только в main.cpp, поэтому переместите его туда. И переменные int могут быть заменены на один enum, потому что кажется, что вы собираетесь использовать их как возвращаемые значения для getToken().

Так что это будет что-то вроде

enum Token { 
    lANGLE=1, rANGLE=2,iD=3,... 
}; 

Token getToken(istream *br, string& lexeme); 
+0

если я изменю int на перечисление, мне нужно будет изменить карту с карты на карту ? Также в главном классе im получение ошибки аргумента типа int несовместимо с параметром type const tokentype & on line: «if (counter.count (typeOfToken)») – curryboy127

+0

Также в основном классе im получается ошибка аргумента типа int несовместим с параметром type const tokentype & on line: «if (counter.count (typeOfToken)») и в счетчике строк [typeofToken] + = 1; есть ошибка в том, что оператор [] не соответствует этим операндам – curryboy127

+0

@ curryboy127, вам не нужно изменять тип 'counter', потому что' enum' неявно конвертируется в 'int', но это не повредит. Я внес изменения в свой код, и он компилируется просто отлично, см. [Demo] (http://coliru.stacked-crooked.com/a/2a3e33100c44d131) –

Смежные вопросы