是这样的,今天看书看到一道程序题,目标是关键字统计,然后给出原来的程序要求改进。
可是坑爹的答案竟然是略,所以前来请教一下各位的高见。
我发现这个程序如果输入的字符太长时会异常终止,所以我想拿这个改进,但奈何功力不够,无从下手。
希望各位能给点建议,如果你有更好的建议,也可以提出来,不过希望可以给一个解释一下,毕竟刚入坑不久,有些思路我跟不上,下面是程序:
#include
#include
#include
#include
#define TABLESIZE 32 /*c语言关键字字数*/
#define MAXWORD 63 /* 标识符最大长度*/
struct key
{
char word;/ C语言关键字数*/
int count; /* 标识符最大长度 */
};
/* C语言关键字列表,出现次数初始化为0*/
struct key keyTable [] = {
"auto", 0,
"break",0,
"case", 0,"char", 0, "const", 0, "continute", 0,
"defaule", 0, "do", 0, "double", 0,
"else", 0, "enum", 0, "extern", 0,
"float", 0,"for", 0,
"goto", 0,
"if", 0,"int", 0,
"long", 0,
"register", 0, "return", 0,
"short", 0, "signed", 0,"sizeof", 0, "static", 0,
"switch", 0,
"typedef", 0,
"union", 0, "unsigned", 0,
"void", 0, "volatile", 0,
"while", 0
};
/*函数声明*/
int GetIdent(FILE *fp, char *word, int lim);
void InComment(FILE *fp);
void InQuote(int c, FILE *fp);
int Search(const char *word, struct key tab[], int n);
void Display(void);
/* 主程序*/
int main (int argc, char *argv[])
{
int n;
char word[MAXWORD];
FILE *fp;
/* 检查命令行的参数个数 */
if (argc != 2)
{
printf("Usage: keyword Filename\n");
exit (1);
}
/* 打开文件 */
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("keyword: can't open%s\n",argv[1]);
exit(1);
}
/*统计关键字*/
while (GetIdent(fp, word, MAXWORD) != EOF)
{ /* 所有C关键字均以字母开头*/
if (isalpha(word[0]))
{ /* 可以用折半查找Bsearch函数替换Search函数 */
if ((n = Search(word, keyTable, TABLESIZE)) >=0)
{
keyTable[n].count++;
}
}
}
/*关闭文件*/
fclose(fp);
/*输出显示统计结果*/
Display();
}
/* 提取标识符*/
int GetIdent(FILE *fp, char *word, int lim)
{
int c, n;
char *w = word;
while (isspace(c = fgetc(fp))){;} /*跳过空格,制表符,换行符 */
/*标识符或宏*/
if (isalpha(c) || c =='_' || c == '#')
{
*w =c ;
while (lim > 0)
{
w++;
*w = fgetc(fp);
if (!isalnum(*w) && *w != '_')
{
ungetc(*w, fp);
break;
}
lim--;
}
}else if(c == '\'' || c == '"') /*单引号和双引号*/
{
InQuote(c, fp);
}else if (c == '/') /* 注释 */
{
if ((n = fgetc(fp)) == '*')
{
InComment(fp);
}else
{
ungetc(n, fp);
}
}
*w = '\0';
return c;
}
/* 处理注释 */
void InComment(FILE *fp)
{
int c,n;
c = fgetc(fp);
n = fgetc(fp);
while (c != '*' || n != '/')
{
c = n;
n = fgetc(fp);
}
}
/*处理引号内 /
void InQuote(int c, FILE *fp)
{
int n;
while ((n = fgetc(fp)) != c)
{
if (n == '\')
{ /引号内释义符后的引号非非后引号*/
n = fgetc(fp);
}
}
}
/* 显示统计结果 */
void Display(void)
{
for (int n = 0; n < TABLESIZE; n++)
{
printf("%4d %s\n",keyTable[n].count, keyTable[n].word);
}
}
/*一般查找,找到返回数组下标,未找到返回-1*/
int Search(const char word,struct key tab[], int n)
{
int cond;
int low = 0;
int high = n - 1;
int mid;
while(low <=high)
{
mid = (low + high)/2;
if((cond = strcmp(word, tab[mid].word))
{
high = mid -1;
}else if (cond > 0)
{
low = mid +1;
}else
{
return mid;
}
}
return -1;/ 未找到 */
}