需求是这样的。写出一个程序,模仿wc.exe,可以统计出文件的一些信息(比如字符数、单词数目等等)
对于这个程序,我仍然用我从大一学来的C语言写的。
第一步:打开文件
1 printf("请输入文件名称"); 2 scanf("%s", filename); 3 transName(filename, outputname); 4 if( ((fp = fopen(filename, "r")) == NULL) || ((output = fopen(outputname, "w")) == NULL) ){ 5 printf("ERROR: 无法打开统计文件"); 6 return 0; 7 }
第二步:读取文件进行处理,这里我采用的是fgets函数来进行按行的读取。
fgets(content, 256, temp); //content: char[] 用来存放读取内容
第三步:对获取到的内容进行处理。
a)获取内容字符数。这里将出空格换行以及tab以外的其他字符都计入统计。代码如下
1 int charCounter(char *content) { 2 int lengh = strlen(content); 3 for (int i = 0; i < strlen(content); i++) 4 { 5 if (32 == content[i] || 10 == content[i] || content[i] == ' ') 6 lengh--; 7 } 8 return lengh; 9 }
b)获取单词数。这里明确,单词应以字母开头,以非字母、数字、点和下划线结尾。所以判断代码如下:
1 bool IsChar(char c) { //判断首字母是否为英文字符 2 if ((c >= 'a'&&c <= 'z') || (c >= 'A'&&c <= 'Z')) 3 return true; 4 return false; 5 } 6 7 bool IsRight(char c) { //用以判断单词结束 8 if (IsChar(c) || c == '.' || c == '_' || (c <= '9'&&c >= '0')) 9 return true; 10 return false; 11 } 12 13 int wordCounter(char *content) { 14 int num = 0; 15 int len = strlen(content); 16 for (int i = 0; i < len; i++) { 17 if (IsChar(content[i])) { 18 while (i<len) { 19 if (!IsRight(content[i++])) 20 { 21 num++; 22 break; 23 } 24 } 25 } 26 } 27 return num; 28 }
c)行数的判断运用到了字符数的判断,判断当这行内容字符数不为0时,为非空行。代码如下:
if (charCounter(content)) line++; //非空行计数+1 else spaceline++; //空行计数+1
d)注释行的判断,针对注释的两种情况,可以在传入内容时传入一个数字flag以确定状态(0:上文中无未结束的"/*" 1:上文中有未结束的"/*")。这样在判断注释行时,首先检察状态。当flag为0时,查找内容,如有"//"则注释行返回true,如有"/*"则将flag置1并返回true。否则,返回false;当flag为1时,只需查找内容中是否有"*/",如有,则置flag为0。这里返回值一定为true。代码如下:
1 bool IsNoteline(char* content,int* flag) { //flag 0:当前无多行注释 1:当前有多行注释 2 if (*flag) { 3 for (int i = 0; i < strlen(content); i++) { 4 if (content[i] == '*' && content[i + 1] == '/') 5 { 6 *flag = 0; 7 } 8 } 9 return true; 10 }else { 11 for (int i = 0; i < strlen(content); i++) 12 { 13 if (content[i] == '/') { 14 if (content[i + 1] == '/') 15 return true; 16 else if (content[i + 1] == '*') 17 { 18 *flag = 1; 19 return true; 20 } 21 } 22 } 23 return false; 24 } 25 }
第四步,格式化输出统计信息。这里采用文件及控制窗口两种方式输出。代码如下:
a)输出文件名称的转换。(默认读取的文件为非txt格式)
1 void transName(char *filename, char *outputname) {//转换文件名,存储统计文件 2 int i; 3 for (i = 0; i < strlen(filename); i++) { 4 if (filename[i] == '.') 5 break; 6 outputname[i] = filename[i]; 7 } 8 outputname[i] = '.'; 9 outputname[++i] = 't'; 10 outputname[++i] = 'x'; 11 outputname[++i] = 't'; 12 outputname[++i] = '