LNK2005错误,已在main.obj中定义

时间:2014-10-25 22:31:23

标签: c++

所以我一直在编写我的代码,而且我不是世界上最好的编码器。我还在学习并认为自己是初学者。我正在为c ++中的概念类编写词法分析。香港专业教育学院尝试了我在网站上看到的解决方案,如在头文件中使用extern并在cpp文件中使用const,但注意到works.when我在两个单独的.cpp文件中包含我的头文件我得到所有int的这个错误在头文件中:

tokens.obj:错误LNK2005:" int eND" (?eND @@ 3HA)已在main.obj中定义

header file =

#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 个答案:

答案 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);