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 "^ ...
随机推荐
- jQuery1.9+ 废弃的函数和方法 升级Jquery版本遇到的问题
面临问题 很久没关注JQuery了,今天突然想升级一下系统中使用的jquery版本,突然发现,升级JQuery版本到1.9之后出现了很多问题,比如:$.browser is undefined.突然就 ...
- 由于没有公钥,无法验证下列签名: NO_PUBKEY 54422A4B98AB5139
gpg --keyserver pgpkeys.mit.edu --recv-key 54422A4B98AB5139 gpg -a --export 54422A4B98AB5139 | sudo ...
- W25Q128BV W25Q128FV W25Q128JV 什么区别?
W25Q128BV W25Q128FV W25Q128JV 什么区别? 官网没有找到 BV 的相关信息, 倒是有 FV,FW,JV,JW 信息..2019年1月19日19:09:55 F ...
- array_sum(),array_product()的使用
这两个函数在你处理数据的时候,相信会很有用处. 一个是处理数组所有值的和,一个是所有值的乘积.写这个随笔就是强调下,有特殊的情况需要注意,以防以后的工作中,统计的时候出现错误. 举个例子: $a = ...
- odoo开发历史订单需求整体思路
第一步:找到客户对应页面,并找到他所下过的销售订单,用数据库语句查出所有数据,并去除重复数据,显示在前端, sql="select DISTINCT t2.product_id as pro ...
- 现有工程中集成Cordova
cocoapods引入cordova源码 1.依赖Cordova和wk插件 pod 'Cordova' pod 'cordova-plugin-wkwebview-engine' 建立Cordova支 ...
- Python3入门(六)——函数式编程
一.高阶函数 1.可以通过变量指向函数,达到类似别名的效果: >>> f = abs >>> f(-10) 10 2.函数的参数可以是函数,也就是函数可以作为一个入 ...
- 20155207 EXP6 信息搜集与漏洞扫描
20155207 EXP6 信息搜集与漏洞扫描 基础问题回答 1)哪些组织负责DNS,IP的管理. ICANN统一管理全球根服务器 全球根域名服务器(13台) 地区性注册机构(5个)ARIN RIPE ...
- web窗体的运用
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebAp ...
- C语言如何向系统接要存
C语言如何向系统接要存,就有这么三种方式: 1.向栈要. 2.向堆要. 3.向数据段要. 这一下就扯出了三种内存空间,内存空间的本质是一样的,一个地址对应一个方框,方框里可以放数据.但是为了更好的去 ...