20150123 【 Linux-C 文件目录操作 】 统计代码行数
2015-01-24 09:46
260 查看
主要是老师要求每天200行,
于是就写了一个用来 统计文件内代码行数的程序。
程序执行时,加上文件夹路径和文件后缀(其实是文件名的片段),
就能统计出 此文件夹下的该类文件的行数以及有效行数(一些用于格式调整【空格,制表,回车】的不算)。
----------------------------
本来还想把注释也干掉的,
可是注释两种情况(单行//和多行/**/)
其中单行好处理;
但是多行要跨行,比较麻烦
所以我就一视同仁,没有处理注释了。
于是就写了一个用来 统计文件内代码行数的程序。
程序执行时,加上文件夹路径和文件后缀(其实是文件名的片段),
就能统计出 此文件夹下的该类文件的行数以及有效行数(一些用于格式调整【空格,制表,回车】的不算)。
----------------------------
本来还想把注释也干掉的,
可是注释两种情况(单行//和多行/**/)
其中单行好处理;
但是多行要跨行,比较麻烦
所以我就一视同仁,没有处理注释了。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <dirent.h> #include <errno.h> /** * 默认文件目录路径 NOW_PATH * 最大文件目录长度 DIR_LEN * 最大文件名长度 FILE_LEN * 最大文件数 FILE_NUM * 默认文件后缀 SUFFIX_NAME */ #define NOW_PATH "." #define DIR_LEN 1024 #define FILE_LEN 512 #define FILE_NUM 520 #define SUFFIX_NAME ".c" //错误描述符 const enum ERROR_STATE{OpenProgarmError=0x77889900, OpenDirError, OpenFileError}; //空白符号集合 blank_char 空白符号数目 blank_len const char blank_char[] = {'\n', '\t', ' ', '\\', '\0'}; const int blank_len = sizeof(blank_char); //默认文件目录路径 dirPath 默认文件后缀 fileSuffix char dirPath[DIR_LEN] = NOW_PATH; char fileSuffix[FILE_LEN] = SUFFIX_NAME; //字符串容器 tempStr 文件数 fLen char tempStr[(DIR_LEN+FILE_LEN)<<2]; int fLen = 0; /** * 文件属性结构体 fileAttr * 文件描述号 fd * 文件行数 len * 文件有效行数 noLen * 文件名称 name */ typedef struct _fileAttr { int fd; int len; int noLen; char name[FILE_LEN]; }fileAttr; //文件属性组 fileAttr fAttr[FILE_NUM]; /** 判断字符串是否都是由空白字符组成的 * 输入参数: 指向目标字符串的字符指针*ss * 函数功能: 判断该字符串是否都是由空白字符(blank_char集合)组成 * 输出参数: 1:都由空白字符组成 0:不是非空字符串 */ int is_blank_line(char *ss) { int i=0, j=0, ssLen=0; //遍历 目标字符串 (一共 ssLen 个字符) for(i=0, ssLen=strlen(ss); i<ssLen; i++) { //简单粗暴的暴力查找(其实可以使用更快的数组定位,但是闲麻烦,就没写了) for(j=0; j<blank_len && blank_char[j]!=ss[i] ; j++); /* * 正常情况下(都不是空白字符), * 遍历完 blank_char 集合才退出 * (此时j=blank_len,说明是非空字符串) */ if( j==blank_len ) return 0; } return 1; } /** 计算该文件的行数(所有行数,有效行数) * 输入参数:文件属性结构体指针 fa * 函数功能:获取该文件所有行,算出有效行数 * 输出参数:无 */ void counter_line(fileAttr *fa) { int i=0; //把文件描述号 fAttr.fd 转换成 文件描述指针 FILE * fp = fdopen(fa->fd, "r"); while( !feof(fp) ) { /* * 读入一行(假设一行不超过 (DIR_LEN+FILE_LEN)<<2 个字符 ) * 统计行数(有效行数) */ fgets(tempStr, (DIR_LEN+FILE_LEN)<<2, fp); fa->len++; fa->noLen += !is_blank_line(tempStr); } } /** 输出该文件目录下所有文件的统计情况 * 输入参数:无 * 函数功能:把文件目录内所有文件信息输出 * 输出参数:无 */ void show_code_counter(void) { int i=0; //统计行数,非空行数 int sumLine=0, sumNoLine=0; //输出标题行(当前路径;文件后缀;序号,代码行数,有效行数,文件名称) printf("\t当前路径:\"%s\"\n", dirPath); printf("\t文件后缀:\"%s\"\n", fileSuffix); printf("---------------------------------------\n"); printf("%4s %8s %8s %s\n", "序号", "代码行数", "有效行数", "文件名称"); //计算该目录下所有文件 for(i=0; i<fLen; i++) { //该文件属性( fAttr.len , fAttr.noLen )初始化 fAttr[i].len = fAttr[i].noLen = 0; //计算该文件行数 fAttr.len , 有效行数 fAttr.noLen counter_line(&fAttr[i]); //输出文件描述号,文件行数,有效行数,文件名称 printf("%4d %8d %8d %s\n", fAttr[i].fd, fAttr[i].len, fAttr[i].noLen, fAttr[i].name); //统计文件 总行数 sumLine , 有效行数 sumNoLine sumLine += fAttr[i].len; sumNoLine += fAttr[i].noLen; } //输出统计信息 总行数 sumLine , 有效行数 sumNoLine printf("---------------------------------------\n"); printf("一共有 %d 个文件,合计 %d 行,有效 %d 行......\n\n\n", fLen, sumLine, sumNoLine); } int main(int argc, char **argv) { int i=0; //程序是否正确打开,失败返回 OpenProgarmError if( argc <= 0 ) { fprintf(stderr, "「程序运行出错」...\n\n"); exit( OpenProgarmError ); } //如果追加路径,则更新文件目录路径 dirPath if( argc >= 2 ) { strncpy(dirPath, argv[1], DIR_LEN); } //如果追加文件后缀,则更新文件后缀 fileSuffix if( argc >=3 ) { strncpy(fileSuffix, argv[2], FILE_LEN); } //打开文件目录目录 fdDir,失败返回 OpenDirError DIR * fdDir = opendir(dirPath); if( fdDir == NULL ) { fprintf(stderr, "「打开目录出错」 %s\n\n", dirPath); exit( OpenDirError ); } /** * 目录内容结构体 f_dirent, * 获取目录内所有文件; * 文件信息有: * 文件描述号 fAttr.fd * 文件名 fAttr.name */ struct dirent * f_dirent = NULL; while( ( f_dirent=readdir(fdDir) ) != NULL ) { //查找目标文件(具有 fileSuffix 后缀的文件) if( strstr(f_dirent->d_name, fileSuffix) ) { //获取文件的绝对或相对路径dirPath/fAttr.name(文件目录路径/文件名) snprintf(tempStr, (DIR_LEN+FILE_LEN)<<2, "%s/%s", dirPath, f_dirent->d_name); //获取文件描述号 fd 和文件名 name fAttr[fLen].fd = open(tempStr, O_RDONLY); strncpy(fAttr[fLen].name, f_dirent->d_name, FILE_LEN); //文件是否打开,失败返回 OpenFileError if( fAttr[fLen++].fd < 0 ) { fprintf(stderr, "「打开文件失败」 %s\n\n", tempStr); exit( OpenFileError ); } } } /* * 输出文件目录路径 dirPath 和文件后缀 fileSuffix * 以及该路径下所有目标文件的: * 文件描述号fd ,文件行数len ,有效行数noLen ,文件名称name * 总计 行数sumLine 和 有效行数sumNoLine */ show_code_counter(); /* * 关闭文件目录 fdDir * 关闭所有文件 fAttr.fd */ closedir( fdDir ); for(i=0; i<fLen; i++) { close( fAttr[i].fd ); } return 0; }
相关文章推荐
- Linux下统计代码行数的方法
- Linux 统计代码行数
- Linux中统计工程代码行数的方法
- Linux: 统计代码行数和SVN修改行数的命令
- Linux 统计代码行数
- linux下统计代码行数
- wc递归统计代码行数 -- Linux/Unix 哲学魅力
- linux 统计代码行数
- [转]Linux统计代码行数
- Linux下统计代码行数
- Linux 统计代码行数
- Linux 统计代码行数
- Linux 统计代码行数
- 【linux命令】代码或文件统计行数
- 自己写代码,替代Linux下的WC完成字符数,行数和单词数的统计
- Linux 统计代码行数
- Linux 统计代码行数
- 【Linux】Linux 统计代码行数
- Linux统计代码行数
- Linux 统计代码行数