从一个C语言源程序文件中 统计出该C程序中使用的关键字及其频率 统计结果表格保存在文件keyword.txt

从一个C语言源程序文件中 统计出该C程序中使用的关键字及其频率 统计结果表格保存在文件keyword.txt 我看了你之前给的回答 但是除了引号内不记录 被注释掉的代码那部分怎么搞 麻烦改改看了…挺麻烦的不知道哪边该取舍 拜托帮帮忙吧

不太清除你和落洛不莫是什么关系,反正那个程序也是我写的。不过现在想来,当时居然下划线没有考虑进,实在是不好意思。嗯,下面说这个程序吧:
(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;
}来自:求助得到的回答
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-12-29
#include<stdio.h>
#include<string.h>
#include<ctype.h>
char *keywords[]={"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 counters[32]={0};
char qw[9];
int get(char s[],FILE *fname) {
int c,i=0;
while(i<=8) {
c=fgetc(fname);
if(c=='/') {
c=fgetc(fname);
if(c=='/')
while((c=fgetc(fname))!='\n')
;
if(c=='*') {
getstar:while((c=fgetc(fname))!='*')
;
if((c=fgetc(fname))=='/')
;
else goto getstar;
}
}
else if(isalpha(c)) s[i++]=c;
else {
if(i!=0) {s[i]='\0';return i;}
i=0;
}
if(c==EOF) return 0;
}
}
int main(int argc,char **argv) {
int n;
FILE *fp;
if(argc!=2) {fprintf(stderr,"wrong input");return 0;}
if((fp=fopen(*++argv,"r"))==NULL) {fprintf(stderr,"can't open %s",*argv);return 0;}
while(get(qw,fp)>0) {
for(n=0;n<32;n++)
if(strcmp(qw,keywords[n])==0) {++counters[n];break;}
}
for(n=0;n<32;++n) {
printf("%-s",keywords[n]);
printf("%3d times ",counters[n]);
}
return 0;
}
运行这个时 visual c 会生成exe文件 比如是h.exe 在同文件夹里建立7..txt(输入)2.txt(输出)在cmd里输入 h.exe 7.txt >2.txt 这三个文件和cmd在一个文件夹里 cmd在C:\WINDOWS\system32本回答被网友采纳
相似回答
大家正在搜