不太清除你和落洛不莫是什么关系,反正那个程序也是我写的。不过现在想来,当时居然下划线没有考虑进,实在是不好意思。嗯,下面说这个程序吧:
(1)由于这个需求实在太复杂了,我只好用状态机做了。
所有可能的状态都在这里,并且旁边都有注释的:enum MY_STATE
不知道你有没有学过状态机,其主要思想就是把各种可能的状态都列出来,然后一个一个考虑。
(2)程序应该还好读懂吧,我已经仔细考虑各种状态两遍了。但这个需求实在太大了,如果还有没考虑进的情况,请多多包含,并欢迎交流。
(3)运行这个程序前,请确保源代码至少能编译通过(我暂时取名为a.c)。虽然我考虑了引号跨行的编译错误,但如果有类似‘do’这种编码的,暂时还是没辙。
下面是源代码:
#include <stdio.h>
#include <string.h>
#define Key_Num 32 //C语言共有32个关键字
#define Len_Min 2 //最短的长度为2
#define Len_Max 8 //最长的长度为8
const char Key[Key_Num][Len_Max+1]={
"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"
};
int count[Key_Num];
char input[Len_Max+1];
void CheckKeyWord(){
int i,result;
for(i=0;i<Key_Num;i++){
result=strcmp(input,Key[i]);
if(result==0){
count[i]++;
break;
}
if(result<0)
break;
}
}
int IsKeyLetter(char c){
return c>='a' && c<='z';
}
int IsOtherLetter(char c){
return c>='A' && c<='Z' ||
c>='0' && c<='9' || c=='_';
}
enum MY_STATE{
INVAILD,//初始时
IN_QUOTE,//引号内
IN_QUOTE_TRANS,//引号内读到转义符
IN_WORD,//有可能是关键词
NOT_KEY,//不是关键词
COMMENT_1,//第一个注释符(/)
COMMENT_LINE,//行注释
COMMENT_BLOCK,//块注释
COMMENT_BLOCK_1//块注释内读到'*'
};
int main(){
FILE *fi;
int i;
enum MY_STATE state;
fi=fopen("a.c","r");
if(fi==NULL) return 1;
i=0;
state=INVAILD;
memset(count,0,sizeof(count));
while(fscanf(fi,"%c",&input[i])==1){
switch(state){
case INVAILD:
if(IsKeyLetter(input[i])){
state=IN_WORD;
i++;
}
else if(IsOtherLetter(input[i]))
state=NOT_KEY;
else if(input[i]=='\"')
state=IN_QUOTE;
else if(input[i]=='/')
state=COMMENT_1;
break;
case IN_QUOTE:
if(input[i]=='\\')
state=IN_QUOTE_TRANS;
else if(input[i]=='\n')//这里漏引号,编译错误。
state=INVAILD;
break;
case IN_QUOTE_TRANS:
if(input[i]=='\n')//这里漏引号,编译错误。
state=INVAILD;
else
state=IN_QUOTE;
break;
case IN_WORD:
if(IsKeyLetter(input[i])){
if(i<Len_Max)
i++;
else{
i=0;
state=NOT_KEY;
}
}
else if(IsOtherLetter(input[i])){
i=0;
state=NOT_KEY;
}
else{
input[i]='\0';
CheckKeyWord();
i=0;
if(input[i]=='\"')
state=IN_QUOTE;
else if(input[i]=='/')
state=COMMENT_1;
else
state=INVAILD;
}
break;
case NOT_KEY:
if(input[i]=='\"')
state=IN_QUOTE;
else if(input[i]=='/')
state=COMMENT_1;
else if(!IsKeyLetter(input[i]) && !IsOtherLetter(input[i]))
state=INVAILD;
break;
case COMMENT_1:
if(input[i]=='/')
state=COMMENT_LINE;
else if(input[i]=='*')
state=COMMENT_BLOCK;
else if(IsKeyLetter(input[i])){
state=IN_WORD;
i++;
}
else if(IsOtherLetter(input[i]))
state=NOT_KEY;
else
state=INVAILD;
break;
case COMMENT_LINE:
if(input[i]=='\n')
state=INVAILD;
break;
case COMMENT_BLOCK:
if(input[i]=='*')
state=COMMENT_BLOCK_1;
break;
case COMMENT_BLOCK_1:
if(input[i]=='/')
state=INVAILD;
else
state=COMMENT_BLOCK;
break;
}
}
fclose(fi);
fi=fopen("keyword.txt","w");
if(fi==NULL) return 1;
for(i=0;i<Key_Num;i++)
fprintf(fi,"%s: %d\n",Key[i],count[i]);
fclose(fi);
return 0;
}来自:求助得到的回答
温馨提示:答案为网友推荐,仅供参考