括号匹配C++程序

括号匹配C++程序
括号匹配C++程序

#include

#include

#include

#include

using namespace std;

/////////////////////////////////////////////

//CBalance类

//此类对于一般的C++或者C文件进行括号匹配检查

//文件可以有注释,字符串……

//字符串常量不可以跨行

//my.h定义了常用的类库

////////////////////////////////////////////

class CBalance

{

private:

ifstream fin; //文件流

int nCurrentLine; //正在处理的行号

int nErrors; //已发现的错误数

struct CSymbol //此类记录遇到的字符和字符的行号

{

char cToken;

int nTheLine;

};

enum CommentType {SlashSlash , SlashStar};//记录//和/*两中注释方式//CheckBalance()函数的工具类

//CheckMatch函数用于比较两个符号是否匹配

bool CheckMatch(char char1, char char2, int nLine1, int nLine2);

//GetNextSymbol函数用于返回读到的括号

char GetNextSymbol(void);

//PutBackChar用于把字符重新返还给文件流

void PutBackChar(char char1);

//SkipComment根据注释符的不同跳过源文件的注释

void SkipComment(enum CommentType type);

//SkipQuote函数用于跳过源文件中的字符串和字符常量

void SkipQuote(char type);

//NextChar函数用于得到下一个字符

char NextChar(void);

public:

CBalance(const char* filename); //构造函数

int CheckBalance(); //检查fin中的字符是否匹配

};

class noFile{}; //定义的异常类,当函数不存在的时候抛出异常CBalance::CBalance(const char* filename)

{

fin.open(filename);

if(!fin) throw noFile();

nCurrentLine = 1;

nErrors = 0;

}

int CBalance::CheckBalance()

{

struct CSymbol node; //符号与行号

stack st; //定义的符号栈

char LastChar,Match; //LastChar为读入的符号,Match为栈顶的字符

while(LastChar = GetNextSymbol())//从文件中读取括号字符,直到文件结束{//while_beigin

switch (LastChar)

{ //switch_beigin

case '(':

case '[':

case '{': //遇到这三种符号要进栈

node.cToken = LastChar;

node.nTheLine = nCurrentLine;

st.push(node);

break;

case ')':

case ']':

case '}'://遇到这三种括号要进行比较

if(st.isEmpty())

{

nErrors++;

cout<<"在第"<

}

else

{

node = st.pop();

Match = node.cToken;

if(!CheckMatch(Match,LastChar,node.nTheLine,nCurrentLine))

nErrors++;

}

break;

}//switch_end

}//while_end

while(!st.isEmpty()) //栈中多余的符号

{

nErrors++;

node = st.pop();

cout<<"第"<

}

return nErrors;

}

bool CBalance::CheckMatch(char char1, char char2, int nLine1, int nLine2)

{

if(char1=='('&&char2!=')'||char1=='['&&char2!=']'||char1=='{'&&char2!='}')

{

cout<<"发现第"<

return false;

}

return true;

}

char CBalance::GetNextSymbol()

{

char ch;

while(ch=NextChar())

{

if(ch=='/')

{

ch=NextChar();

if(ch=='/')

SkipComment(SlashSlash);

else if(ch=='*')

SkipComment(SlashStar);

else PutBackChar(ch);

}

else if (ch=='\''||ch=='"')

{

SkipQuote(ch);

}

else if (ch=='['||ch=='{'||ch=='('||ch==']'||ch=='}'||ch==')')

{

return ch;

}

return NULL;

}

char CBalance::NextChar()

{

char ch;

if((ch=fin.get())==EOF)return NULL;

if(ch=='\n')

nCurrentLine++;

return ch;

}

void CBalance::PutBackChar(char char1)

{

fin.putback(char1);

if(char1=='\n') nCurrentLine--;

}

void CBalance::SkipQuote(char type)

{

char ch;

while(ch=NextChar())

{

if(ch==type) return;

else if (ch=='\n')

{

nErrors++;

cout<<"在第"<

}

else if (ch=='\\')

{

ch = NextChar();

}

}

}

void CBalance::SkipComment(enum CommentType type)

{

char ch,flag;

if(type==SlashSlash) //对于像//注释一直读到行末尾

{

while ((ch=NextChar())&&(ch!='\n'))

{

return;

}

flag='\0'; //对于像/*这样的注释要不断的读文件while((ch=NextChar())!=NULL)

{

if(flag=='*'&&ch=='/')

return;

flag = ch;

}

}

int main()

{

try

{

CBalance b("123.txt"); //文件要在工程当前目录下

b.CheckBalance();

}

catch (noFile& file)

{

cout <<"文件打开失败!"<

}

return 0;

}

相关主题
相关文档
最新文档