需求分析:

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

  • 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. apache不能启动LoadModule php5_module modules/ph

    apache不能启动LoadModule php5_module modules/php5apache2.dll的问题 主要是版本问题!!有点不爽!! apache不能启动 加入下面两行,apache ...

  2. Java继承访问权限

    JAVA 子类重写继承的方法时,不可以降低方法的访问权限,子类继承父类的访问修饰符要比父类的更大,也就是更加开放,假如我父类是protected修饰的,其子类只能是protected或者public, ...

  3. 使用iozone进行磁盘读写性能测试

    对于很多GIS工程师,经常需要对系统的磁盘性能进行测试,为了排查问题或者帮助用户进行系统设计. IOZone这个磁盘性能测试工具就是一个很方便的辅助工具. 下面就以个测试共享目录的读写性能为例,说明其 ...

  4. kubernetes 的wen pod 无法连接 mysql 的pod

    1.分析 查看源代码 既然无法建立连接,那先看下是如何建立连接的.登录到myweb的docker容器里面,查看index.jsp文件,主要内容如下: Class.forName("com.m ...

  5. 20155206 Exp2 后门原理与实践

    20155206 Exp2 后门原理与实践 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机IP 然后使用ncat.exe程序,ncat. ...

  6. 5213 Exp3 免杀原理与实践

    5213 Exp3 免杀原理与实践 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等免杀工具或技巧 使用msf编码器 ...

  7. 《Flask Web开发实战:入门、进阶与原理解析(李辉著 )》PDF+源代码

    一句话评价: 这可能是市面上(包括国外出版的)你能找到最好的讲Flask的书了 下载:链接: https://pan.baidu.com/s/1ioEfLc7Hc15jFpC-DmEYBA 提取码: ...

  8. Eclipse中Maven插件配置

    1. Maven插件配置 http://www.blogjava.net/fancydeepin/archive/2012/07/13/eclipse_maven3_plugin.html 2. Ma ...

  9. 4556: [Tjoi2016&Heoi2016]字符串

    4556: [Tjoi2016&Heoi2016]字符串 链接 分析: 首先可以二分这个长度.此时需要判断是否存在一个以b结尾的前缀,满足与[c,d]的lcp大于等于mid. 如果我们把串翻转 ...

  10. Visual Studio Package 插件开发(Visual Studio SDK)

    背景 这段时间公司新做了一个支付系统,里面有N个后台服务,每次有更新修改,拷贝打包发布包“不亦乐乎”...于是我想要不要自己定制个打包插件. 部分朋友可能会认为,有现成的可以去找一个,干嘛不用持续集成 ...