需求分析:

程序处理用户需求的模式为:

  • 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----命令行实现对文件信息的统计的更多相关文章

  1. (第三周)wc.exe—命令行实现对指定目录下文件的操作

    一.用户需求 程序处理用户需求的模式为: wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下: 1.基本功能 支持 -c ...

  2. c# 借助cmd命令解析apk文件信息

    借助aapt.exe文件 aapt.exe 解析apk包信息cmd命令: aapt dump badging *.apkaapt d badging *.apk >1.txt(保存成1.txt文 ...

  3. linux中wc命令

    目录 一:linux中wc命令 1.wc命令介绍 2.wc命令作用 3.wc命令格式 4.参数 5.解析案例 一:linux中wc命令 1.wc命令介绍 Linux wc命令用于计算字数. 利用wc指 ...

  4. wc命令统计目录下所有文件行数

    想统计一下最近一个项目的代码行数,一个一个文件统计显然不是程序员的思维,wc命令可以统计一个文本的行数,结合find命令可以实现我的需求(注意符号):

  5. Linux下wc命令统计文件行数/词数/字符数/最长行字符数

    wc命令帮助 $ wc --help Usage: wc [OPTION]... [FILE]... or: wc [OPTION]... --files0-from=F Print newline, ...

  6. shell的wc命令统计 head tail命令详解

    Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...

  7. wc命令——Linux系统高效数据统计工具

    wc(world count)是一个统计文件字词,字节,行数的Linux命令,它可以帮我们非常方便的统计以上信息. 主要参数 常见参数如下: -c 统计字节数. -l 统计行数. -m 统计字符数.这 ...

  8. shell 命令 文件查看ls,复制cp,移动mv,查看文件内容cat more less,查看文件信息 file

    1. 查看文件 ls        ls -l  查看文件详细信息 ls -a 查看所有文件(包含隐藏文件) ls -lh  带单位显示文件大小 ls -i  查看文件的节点号(相当身份证唯一)  2 ...

  9. Linux统计文件夹下文件信息

    统计当前文件夹里面有多少文件,即统计文件个数 ls -l |grep "^-"|wc -l 统计当前文件夹里面有多少文件夹,即统计文件夹个数 ls -l |grep "^ ...

随机推荐

  1. 'No Transport' Error w/ jQuery ajax call in IE

    I need to use foursquare API to search venues. Of course it is cross-domain. It has no any problems ...

  2. [CTSC2018]混合果汁

    题目连接:https://www.luogu.org/problemnew/show/P4602 因为题中说是让最小值最大,所以自然想到二分答案.对于每一个二分的值,判断是否合法,若合法,在右区间二分 ...

  3. Springboot集成Common模块中的的全局异常处理遇见的问题

    由于项目公共代码需要提取一个common模块,例如对于项目的文件上传,异常处理等,本次集成common代码时候maven引入common的全局异常处理代码之后发现不生效,由于common包路径与自己的 ...

  4. javascrpt each map

    each方法: 定义一个空数组,通过each方法,往数组添加ID值:最后将数组转换成字符串后,alert这个值: $(function(){ var arr = []; $(":checkb ...

  5. 非阻塞 sleep

    在OpenResty里面选择使用库的时候,有一个基本的原则:尽量使用ngx Lua的库函数,尽量不用Lua的库函数,因为Lua的库都是同步阻塞的. 再来一个例子来说明阻塞API的调用对nginx并发性 ...

  6. Android 配置从GitHub上下载下来的不太规则的源代码库,并保证程序正常运行

    用过github的朋友一定会发现,我们在github上下载下来的源代码(例子和库),放到eclipse中并不是总能正常运行的,它有可能会出现这样或者那样的错误,例如:找不到jar包,配置文件错误,R文 ...

  7. SystemView SEGGER FreeRTOS 移植和使用

    /* 官方帮助英文翻译文档参考:https://blog.csdn.net/bjr2016/article/category/7275877. */ /* 移植文档参考:https://blog.cs ...

  8. allegro中Autosilk top, Silkscreen top 和Assembly top三个什么区别(转)

    allegro中Autosilk top, Silkscreen top 和Assembly top三个什么区别(转) Autosilk top, Silkscreen top 和Assembly t ...

  9. 基于LBS平台的iOS开发

    LBS,即Location Based Services,基于位置服务,用于定位.导航等功能,比如地图应用.订外卖等的app就需要这个功能. 在这里我使用的是高德LBS开放平台,地址:http://l ...

  10. # 2017-2018-2 20155319『网络对抗技术』Exp2:后门原理与实践

    2017-2018-2 20155319『网络对抗技术』Exp2:后门原理与实践 1.实验准备 一.实验说明 任务一:使用netcat获取主机操作Shell,cron启动 (0.5分) 任务二:使用s ...