📄 chk.c
字号:
/*-
* chk - word count and C program check
*
* Usage: chk [file...]
*
* Count lines, words, and characters in the named files or stdin.
* Words are delimited by spaces, tabs, or newlines. Default action is
* -lwc.
*
* Flags:
* -l display number of lines
* -w display number of words
* -c display number of characters
* 本程序主要可以对一个c语言程序中的括号和注释情况进行检查,可以快速地发现原程序
* 中隐含的语法匹配性错误,可以根据检查结果,对不匹配的括号进行修改,最快速度地将
* 程序修改正确。同时本程序也可以象wc程序一样对一个程序进行计数统计,得到一个文件
* 的行、单词、字节的统计结果。
*
*/
#include <stdio.h>
#include <ctype.h>
/* Totals in case multiple files are specified. */
long totnlines = 0L;
long totnwords = 0L;
long totnchars = 0L;
/* 在外部集中定义了对所有文件进行统计的变量。*/
int nfiles = 0; /* Number of files specified. */
main(argc, argv)
int argc;
char **argv;
{
void check();
int lines = 0; /* Count lines? 行计数器 */
int words = 0; /* Count words? 单词计数器 */
int chars = 0; /* Count chars? 字节计数器 */
int optind; /* Loop index. 输入控制索引标志 */
for (optind = 1; optind < argc && *argv[optind] == '-'; ++optind)
while (*++argv[optind])
switch (*argv[optind]) {
case 'l': lines = 1; break;
case 'w': words = 1; break;
case 'c': chars = 1; break;
default:
fprintf(stderr, "Usage: chk [-lwc] [C progaram file...]\n");
exit(1);
}
/* 以上的程序主要是动作的控制索引 */
if (lines + words + chars == 0)lines = words = chars = 1;
/* 本程序缺省的检查是对‘行、词、字节’进行全面的计数。 */
if (optind == argc) { check("-", lines, words, chars); exit(0); }
/* 对于最后一个操作时,可以在执行程序后,退出系统。*/
for (; optind < argc; ++optind) check(argv[optind], lines, words, chars);
/* 对所有的文件进行统计操作 */
if(nfiles >1){
printf("\n Total %1d files have:", nfiles);
printf("\t%4ld lines, \t%4ld words, \t%4ld chars\n",
totnlines, totnwords, totnchars);
}
/* 程序打印整个统计的汇总结果。*/
return (0);
}
/*
* Calculate and output the specified counts.
*/
void
check(file, lines, words, chars)
char *file;
char lines, words, chars;
{
char *normalize();
FILE *fp; /* Input file pointer. */
int RDint; /* One byte of input. */
long nlines = 0L; /* Number of lines in current file. */
long nwords = 0L; /* Ditto for words. */
long nchars = 0L; /* Ditto for characters. */
char inword = 0; /* Were we in a word before this char? */
int Count_num[10], line; /* 各种括号匹配情况统计变量表。 */
/*
Count_num[0] of '{' total, Count_num[1] of '}' total;
Count_num[2] of '[' total, Count_num[3] of ']' total;
Count_num[4] of '(' total, Count_num[5] of ')' total;
Count_num[6] of '\*' total, Count_num[7] of '*\' total;
*/
for(line=0;line<10; Count_num[line]=0, line++); /* 括号统计变量初始化 */
++nfiles;
if (!strcmp(file, "-"))fp = stdin;
if (!(fp = fopen(file, "r"))) { perror(file); return; }
while ((RDint = fgetc(fp)) != EOF)
{
++nchars;
switch (RDint)
{
case '\n':
++nlines;
case '\t':
case ' ':
if (inword) ++nwords;
inword = 0;
break;
case '{':
Count_num[0] ++;
break;
case '}':
Count_num[1] ++;
break;
case '[':
Count_num[2] ++;
break;
case ']':
Count_num[3] ++;
break;
case '(':
Count_num[4] ++;
break;
case ')':
Count_num[5] ++;
break;
case '/':
RDint=fgetc(fp);
if(RDint=='*') Count_num[6]++;
break;
case '*':
RDint=fgetc(fp);
++ nchars;
if(RDint=='/') Count_num[7] ++;
if(RDint=='(') Count_num[4] ++;
if(RDint==')') Count_num[5] ++;
if(RDint=='*'){
RDint=fgetc(fp);
++ nchars;
if(RDint=='/') Count_num[7] ++;
if(RDint=='(') Count_num[4] ++;
if(RDint==')') Count_num[5] ++;
}
break;
default:
inword = 1;
break;
}
}
if (inword) { ++nlines; ++nwords; }
totnlines += nlines;
totnwords += nwords;
totnchars += nchars;
/* 进行汇总结果的统计工作。*/
printf("\n%s have:", normalize(file));
if (lines) printf("\t%2ld lines", nlines);
if (words) printf("\t%2ld words", nwords);
if (chars) printf("\t%2ld chars", nchars);
printf("\n");
/* 打印本文件中的单词统计结果。*/
printf("\t{<->}\t\t[<->]\t\t(<->)\t\t/*<->*/\n");
printf("\t%1d<->%1d\t\t%1d<->%1d\t\t%1d<->%1d\t\t%1d<->%1d\n",
Count_num[0], Count_num[1], Count_num[2], Count_num[3],
Count_num[4], Count_num[5], Count_num[6], Count_num[7]);
/* 打印括号检测结果。 */
/*
if (fp != stdin) printf(" %s", normalize(file));
printf("\n");
*/
if (fp != stdin) (void) fclose(fp);
}
/*
* Convert uppercase letters to lowercase, and non-graphic characters to
* '?'.
* 以下的子程序可以对读入的文件名字进行处理,在结果输出时用。
* 对于非ascii码和非打印字符进行了处理。
*/
char *
normalize(s)
char *s;
{
char *t;
for (t = s; *t; ++t)
if (!isascii(*t) || !isgraph(*t)) *t = '?';
else
if (isupper(*t) && *t != '_')
/* Aztec C's ctype thinks that isupper('_') is true . . . */
*t = tolower(*t);
return s;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -