WC----命令行实现对文件信息的统计
需求分析:
程序处理用户需求的模式为:
- wc.exe [parameter][filename]
在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下:
1、基本功能
- 支持 -c 统计文件字符数
- 支持 -w 统计文件单词数
- 支持 -l 统计文件总行数
2、拓展功能
- 支持 -a 返回高级选项(代码行 空行 注释行)
[filename] 是待处理文件名。
能力有限,没有写出来-s:递归处理目录下符合条件的文件的功能,高级功能-x。
基本功能的实现:
这次写的程序条理还比较清晰,实现四个功能写了四个子,函数其中void CharCount(FILE *fp),用于统计文件中字符的数量,void WordCount(FILE *fp),用于统计文件中单词的数量,void LineCount(FILE *fp),用于统计文件的行数,void Advance(FILE *fp),实现统计文件中的代码行,注释行,空行的数量。
利用main函数的参数传递输入内容,使用命令行程序cmd调试参数。由于没想到怎么来控制不确定参数个数的情况,只能机械的自己排序,然后判断输入情况进行程序调试与运行。之前以为自己不会用文件,现在感觉挺简单的嘛。定义文件指针保存文件地址。然后根据输入参数个数的情况进行不同情况的函数调用,偷懒了,没有把参数大于三个时的情况都写下来。肯定有宝藏待我发掘。在主函数中获得参数内容,根绝参数内容进入不同的子函数输出不同的内容。主函数代码如下:
int main(int argc, char* argv[])
{
FILE *fp;
switch(argc)
{
//不同的输入情况
case :
fp=fopen(argv[],"r");
if(fp==NULL)
{
printf("不能打开文件");
exit();
}
if(strcmp(argv[],"-c")==)
{
CharCount(fp);
}
else if(strcmp(argv[],"-w")==)
{
WordCount(fp);
}
else if(strcmp(argv[],"-l")==)
{
LineCount(fp);
}
else if(strcmp(argv[],"-s")==)
{
Advance(fp);
}
else
{
printf("格式错误!\n");
}
break;
case :
fp=fopen(argv[],"r");
if(fp==NULL)
{
printf("不能打开文件");
exit();
}
if(strcmp(argv[],"-c")==)
{
if(strcmp(argv[],"-w")==)
{
CharCount(fp);
WordCount(fp);
}
else if(strcmp(argv[],"-l")==)
{
CharCount(fp);
LineCount(fp);
}
else
{
printf("格式错误!\n");
}
}
else if(strcmp(argv[],"-w")==&&
strcmp(argv[],"-l")==)
{
WordCount(fp);
LineCount(fp);
}
else
{
printf("格式错误!\n");
}
break;
case :
fp=fopen(argv[],"r");
if(fp==NULL)
{
printf("不能打开文件");
exit();
}
if((strcmp(argv[],"-c")==)&&
(strcmp(argv[],"-w")==)&&
(strcmp(argv[],"-l")==))
{
CharCount(fp);
WordCount(fp);
LineCount(fp);
}
else
{
printf("格式错误!\n");
}
break;
case :
fp=fopen(argv[],"r");
if(fp==NULL)
{
printf("不能打开文件");
exit();
}
if((strcmp(argv[],"-c")==)&&
(strcmp(argv[],"-w")==)&&
(strcmp(argv[],"-l")==)&&
(strcmp(argv[],"-s")==))
{
CharCount(fp);
WordCount(fp);
LineCount(fp);
Advance(fp);
}
else
{
printf("格式错误!\n");
}
break;
default:
{
printf("参数个数不正确!\n");
exit();
}
}
return ;
}
测试文件如下,第一行没有字符直接回车,第二行三个空格一个tab行缩进,主要用来测试空行:

当捕捉到用户的输入的指令含有-c时,调用统计文件中字符的数量的函数,每读取一个字符,字符数量增加一,最后输出总字符的数量。最后把文件的指针重新指向文件流的开头,避免其他函数读文件时出错。代码和程序运行截图如下:
void CharCount(FILE *fp)
{
int charcount=;
char ch;
ch=fgetc(fp);
//使用feof函数判断文件是否结束,feof函数适合于各种文件
//读取一个字符,字符数增1
while(!feof(fp))
{
charcount++;
ch=fgetc(fp);
} printf("字符数:%d\n",charcount);
//文件指针指向流的开头
rewind(fp);
}

当捕捉到用户输入的指令含有-w时,调用统计文件中单词的数量的函数,我把单词定义为字母数字或者下划线开头并且由字母数字或下划线构成的字符串,所以每当第一个字符属于字母数字或者下划线的话这个字符串至少有一个单词了,然后继续往下读字符,直到下个字符不是字母数字或者下划线,然后单词数量增一。单个数字也会被当成字符串,可以把第一个字符的判断改成字母或者下划线就行了,判断是不是字母可以用isalpha函数。isalnum函数用来判断是不是字母或者数字。下划线的ASCII码为95,也可以直接写:'_'。代码和程序运行截图截图如下:
void WordCount(FILE *fp)
{
int wordcount=;
char ch;
ch=fgetc(fp);
while(!feof(fp))
{
//字母数字或者下划线开头
if(isalnum(ch)||ch==)
{
//而且后续字符也是字母数字或者下划线
while(isalnum(ch)||ch==)
{
ch=fgetc(fp);
}
//单词数量增加1
wordcount++;
} ch=fgetc(fp);
}
printf("单词数:%d\n",wordcount);
rewind(fp);
}

当捕捉到用户输入的指令含有-l时,调用统计文件的行数的函数,每遇到’\n‘或者’\0‘时,行数加一。代码和程序运行截图如下:
void LineCount(FILE *fp)
{
int linecount=;
char ch;
ch=fgetc(fp);
//遇到换行符或者文件结尾行数增1
while(!feof(fp))
{
if(ch=='\n'||ch=='\0')
{
linecount++;
}
ch=fgetc(fp);
} printf("行数:%d\n",linecount+);
rewind(fp);
}

基本功能指令统一输入的截图如下:

部分扩展功能的实现:
void Advance(FILE *fp),实现统计文件中的代码行,注释行,空行的数量。
判断规则:空行:本行全为空行或是格式控制字符,若包含代码,则只有不超过一个可显示字符,如 "{";注释行:含有“//”的行,如果是代码+“//”,也把这一行当做注释行;代码行:除去空行和注释行的其他行。
因为统计的单位是行,所以这次是一次读一行的内容,方便统计。然后根据每行的内容对不同变量进行增一的操作。代码和程序运行的截图如下:
void Advance(FILE *fp)
{
//代码行
int CodeLine=;
//空行
int EmptyLine=;
//注释行
int AnnotaLine=;
int i=;
int linecount=;
char ch,str[]; //获取总行数
ch=fgetc(fp);
while(!feof(fp))
{
if(ch=='\n'||ch=='\0')
{
linecount++;
}
ch=fgetc(fp);
}
rewind(fp);
while(!feof(fp))
{
//读取一行字符串来判断每行状态
fgets(str,sizeof(str),fp);
//空行
if(str[]=='\n')
{
EmptyLine++;
continue;
}
//空行
for(i=;str[i]!='\n';i++)
{
//本行代码含有大括号
if(str[i]=='{'||str[i]=='}')
{
//大括号后面没有代码,空行增1,读取下一行
if(str[i+]=='\n')
{
EmptyLine++;
goto ABC;
}
else
{
//大括号后面是空或者tab,继续判断下一个字符
while(str[i+]==' '||str[i+]=='\t')
{
i++;
//满足循环条件且最后是换行符,空行增1
if(str[i+]=='\n')
{
EmptyLine++;
goto ABC;
}
}
}
}
else
//本行代码只有空行或者tab,空行增1
while(str[i]==' '||str[i]=='\t')
{
i++;
if(str[i]=='\n')
{
EmptyLine++;
goto ABC;
} } }
//注释行加1
for(i=;str[i]!='\n'&&str[i]!='\0';i++)
{
//判断第一个字符是不是注释字符
if(str[i]=='/')
{
//判断第二个字符,是的话注释行增1
if(str[i+]=='/')
{
AnnotaLine++;
break;
}
//不是的话直接跳出循环,减少时间耗费
else
break;
} } ABC:;
}
printf("空行:%d\n",EmptyLine);
printf("注释行:%d\n",AnnotaLine);
//总行数减去空行和注释行得到代码行数
printf("代码行:%d\n",linecount-EmptyLine-AnnotaLine+);
}

代码基本功能和部分高级功能已经全部实现,附上综合到一块的程序运行的截图:

总结:程序的基本功能实现的还是比较顺利的,但是高级功能的实现很艰难,只是空行一项内容我就花费了好几个小时去思考,真的想了,但就是没有思路。现在即便写出来了也还是有很多bug。底层人民的悲哀那,看着人家快准狠的写完程序,自己努力奋斗只是个残次品,不受打击是不可能的。但是也很无奈。
WC----命令行实现对文件信息的统计的更多相关文章
- (第三周)wc.exe—命令行实现对指定目录下文件的操作
一.用户需求 程序处理用户需求的模式为: wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下: 1.基本功能 支持 -c ...
- c# 借助cmd命令解析apk文件信息
借助aapt.exe文件 aapt.exe 解析apk包信息cmd命令: aapt dump badging *.apkaapt d badging *.apk >1.txt(保存成1.txt文 ...
- linux中wc命令
目录 一:linux中wc命令 1.wc命令介绍 2.wc命令作用 3.wc命令格式 4.参数 5.解析案例 一:linux中wc命令 1.wc命令介绍 Linux wc命令用于计算字数. 利用wc指 ...
- wc命令统计目录下所有文件行数
想统计一下最近一个项目的代码行数,一个一个文件统计显然不是程序员的思维,wc命令可以统计一个文本的行数,结合find命令可以实现我的需求(注意符号):
- Linux下wc命令统计文件行数/词数/字符数/最长行字符数
wc命令帮助 $ wc --help Usage: wc [OPTION]... [FILE]... or: wc [OPTION]... --files0-from=F Print newline, ...
- shell的wc命令统计 head tail命令详解
Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...
- wc命令——Linux系统高效数据统计工具
wc(world count)是一个统计文件字词,字节,行数的Linux命令,它可以帮我们非常方便的统计以上信息. 主要参数 常见参数如下: -c 统计字节数. -l 统计行数. -m 统计字符数.这 ...
- shell 命令 文件查看ls,复制cp,移动mv,查看文件内容cat more less,查看文件信息 file
1. 查看文件 ls ls -l 查看文件详细信息 ls -a 查看所有文件(包含隐藏文件) ls -lh 带单位显示文件大小 ls -i 查看文件的节点号(相当身份证唯一) 2 ...
- Linux统计文件夹下文件信息
统计当前文件夹里面有多少文件,即统计文件个数 ls -l |grep "^-"|wc -l 统计当前文件夹里面有多少文件夹,即统计文件夹个数 ls -l |grep "^ ...
随机推荐
- moand的编程学形式:一个(高阶)类型包办程序的组织--类型关乎复合
moand的编程学形式:一个(高阶)类型完成程序的组织. 将类型系统的转换与高阶函数进行了融合,相对于链式编程而言. 类型关乎复合 范畴论与箭头的复合有关.但是并非任意两个箭头都可以复合.一个箭头的目 ...
- php可逆加密解密
函数: function encrypt($data, $key) { $prep_code = serialize($data); $block = mcrypt_get_block_size('d ...
- MetaMask/json-rpc-engine
https://github.com/MetaMask/json-rpc-engine RpcEngine——MetaMask/json-rpc-engine https://github.com/M ...
- Java继承访问权限
JAVA 子类重写继承的方法时,不可以降低方法的访问权限,子类继承父类的访问修饰符要比父类的更大,也就是更加开放,假如我父类是protected修饰的,其子类只能是protected或者public, ...
- JS添加标签效果
JS添加标签效果 在豆瓣网上添加自己的标签是一种常见的效果,今天也就做了一个简单的demo.由于时间的问题 我不多原理,大家可以试着操作几遍就能明白其中的原理了. JSFiddle的效果如下: 点击我 ...
- PAT B1030 完美数列 (25 分)
给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格 ...
- day68
昨日回顾:1 虚拟环境 -1 pycharm里创建 -2 用命令串讲2 视图层: 1 Request对象---GET,POST,method,body,FILES,META,path(只是路径),ge ...
- 【本地服务器】json-server搭建本地https服务器(windows)
(一)用json-server搭建简单的服务器 (搭建出来的服务器地址为localhost:3000) 1.新建Mockjson文件夹,进入该文件夹目录,运行命令 npm install -g jso ...
- CentOS 建立本地yum源服务器
安装CentOS系统,配置系统的网络环境 配置静态IP vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 TYPE=Ethernet O ...
- c# 菜鸟包裹查询
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...