需求分析:

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

  • 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. C借函数指针构造映射

    这是候老师的<深入浅出 MFC>中C借函数指针构造映射截图,可以看到MFC们的映射思想:

  2. python第三十一课--递归(3.递归的弊端)

    演示递归的弊端: def mySum(num): if num == 1: return 1 return num+mySum(num-1) mySum(998) [注意]:递归可以解决绝大多数循环能 ...

  3. BZOJ3787:Gty的文艺妹子序列(分块,树状数组)

    Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...

  4. Scala学习之路 (十)Scala的Actor

    一.Scala中的并发编程 1.Java中的并发编程 ①Java中的并发编程基本上满足了事件之间相互独立,但是事件能够同时发生的场景的需要. ②Java中的并发编程是基于共享数据和加锁的一种机制,即会 ...

  5. Android开发-各种各样好看漂亮的进度条,指示器,加载提示汇总

    导读:之前项目中用到一些进度条,找了不少,打算写个demo自己总结一下,留着以后用, 有些是自己写的,有些是github上找的别人的库,如果大家觉得好看可以用,直接下载复制代码到项目里就可以用,ok ...

  6. setattr

    setatt r给对象的属性赋值,若属性不存在,先创建再赋值 用法 setattr(object, name, values) object -- 对象. name -- 字符串,对象属性. valu ...

  7. Android MD5算法

    package com.example.myapi.md5; import java.io.UnsupportedEncodingException; import java.security.Mes ...

  8. IC设计推荐书籍

    IC设计推荐书籍 听语音 | 浏览:779 | 更新:2014-07-19 10:52 1 2 3 4 5 6 7 分步阅读 接触IC设计这一行已经有7年的时间了,前面4年是大学本科,用来学习知识,现 ...

  9. 20155226 《网络对抗》exp6信息搜集与漏洞扫描

    20155226 <网络对抗>exp6信息搜集与漏洞扫描 实验后回答问题 哪些组织负责DNS,IP的管理? 目前域名机构主要包括ICANN理事会和CNNIC. Internet 域名与地址 ...

  10. mount状态下表空间情报试验

    SQL> shutdown immediate;Database closed.Database dismounted.ORACLE instance shut down.SQL> sta ...