所以我一直在编写我的代码,而且我不是世界上最好的编码器。我还在学习并认为自己是初学者。我正在为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;
}
答案 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);