wc基础功能
2018-09-24 19:21 星河流放 阅读(337) 评论(0) 编辑 收藏 举报第一次作业
项目地址
https://gitee.com/xxlznb/WordCount
PSP
WordCount | 预估耗时(分钟) | 实际耗时 |
---|---|---|
计划 | 20 | 30 |
预估任务需要时间 | 20 | 30 |
开发 | 380 | 465 |
需求分析 | 20 | 25 |
设计文档 | 10 | 5 |
代码规范 | 10 | 5 |
具体设计 | 40 | 20 |
具体编码 | 240 | 320 |
代码复审 | 40 | 30 |
测试 | 20 | 60 |
报告 | 50 | 45 |
测试报告 | 10 | 15 |
计算工作量 | 10 | 10 |
事后总结 | 30 | 20 |
合计 | 450 | 540 |
思路
WordCount的基础功能是
-
统计字数
统计字数,只需要将文件中的单词一个个读取出来就行。
-
统计单词数
对于一个文本而言,其内容可以抽象为单词+符号,也就是说,计算符号的间隔即可
-
统计行数
读取文本中的换行符即可
我的开发平台为Linux,为了符合Linux的基础要求,参考书目为《UNIX环境高级编程(第三版)》
程序实现过程
程序分为两个主要步骤在主函数中我们只需要调用这两个函数
-
解析参数
解析参数,我把参数分为三类,短选项、长选项、文件名,
- 短参数,以
-
开始后紧跟一个字符,短参数可以叠加使用,也可以单独使用,例如-c -l -w
- 长参数,短参数在使用频繁的时候可能造成输入麻烦,因此,你可以将短参数直接写在一个
-
后,例如-c -l -w [file]
可直接简写为-clw [file]
顺序和内容都自由更改 - 文件名称,文件名称位于参数后,且如果没有参数则会报错,如果一个参数后紧跟多个文件名,则对多个文件执行同等的操作,例如
-clw [file1] [file2]
,但-o
参数除外,-o
只能指定一个文件
对于参数解析采取宽容方式
-c -c [file]
重复参数不报错。具体做法为构造一个解析链表,将解析结果存入链表中
同时将执行模式存入其中,为了节约储存空间,将模式直接放入一个
int
中,之后判断int
的位就可以知道它的模式 - 短参数,以
-
统计内容
统计内容为了方便添加功能,将每个功能单独写一个函数,之后调用函数即可。
代码说明
void putInfo(int x)
{
if(root==NULL)
{
root=(Info*)malloc(sizeof(Info));
root->mode=x;
root->path=NULL;
root->next=NULL;
tail=root;
}
else
{
if(tail->path!=NULL)
{
tail->next=(Info*)malloc(sizeof(Info));
tail=tail->next;
tail->mode=x;
tail->path=NULL;
tail->next=NULL;
}
else
{
tail->mode=(tail->mode|x);
}
}
}
void longArg(char* arg)
{
int length=strlen(arg);
int i,x=0;
for(i=1;i<length;i++)
{
switch(arg[i])
{
case 'c':x=x|c;break;
case 'w':x=x|w;break;
case 'l':x=x|l;break;
default:
{
fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),arg);
exit(1);
}
}
}
putInfo(x);
}
void argParsing(int argc,char* argv[])
{
char* temp=NULL;
int i=1;
while(i<argc)
{
if(strcmp(argv[i],"-c")==0)
{
putInfo(c);
}
else if(strcmp(argv[i],"-w")==0)
{
putInfo(w);
}
else if(strcmp(argv[i],"-l")==0)
{
putInfo(l);
}
else if(strcmp(argv[i],"-o")==0)
{
if(i<argc-1 && argv[i+1][0]!='-')
{
outFilePath=argv[i+1];
i++;
}
else
{
fprintf(stderr,"wc:error:'-o' argument no outputfile\n");
exit(1);
}
}
else if(argv[i][0]=='-')
{
if(strlen(argv[i])>2)
{
longArg(argv[i]);
}
else
{
fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),argv[i]);
exit(1);
}
}
else
{
if(tail!=NULL)
{
if(tail->path!=NULL)
{
putInfo(tail->mode);
}
tail->path=argv[i];
}
else
{
fprintf(stderr,"wc:error:%s of '%s'\n",strerror(EINVAL),argv[i]);
exit(1);
}
}
i++;
}
if(root==NULL||tail->path==NULL)
{
fprintf(stderr,"wc:error:no input file\n");
exit(1);
}
if(outFilePath==NULL)outFilePath="result";
}
这是解析的相关函数,主要就体现一个if else
。就考虑到所有的方面就行了,代码有问题的地方在与可复用性不高,而且扩展行差。后期再想办法吧。
测试设计
创建一个test.sh
文件,内容如下:
#!/bin/bash
gcc wc.c -o wc -D PRINT -D NOCOUNT
./wc -c -c -l -w file1
./wc -clw file1 file2
./wc -clw file1 -cl file2
./wc -c
./wc file1
./wc -e file1
./wc -el file1
./wc -o
./wc -l -o outfile file
./wc -
./wc
输出内容如下
7,file1
7,file1
7,file2
7,file1
5,file2
wc:error:no input file
wc:error:Invalid argument of 'file1'
wc:error:Invalid argument of '-e'
wc:error:Invalid argument of '-el'
wc:error:'-o' argument no outputfile
1,file
wc:error:Invalid argument of '-'
wc:error:no input file
白盒测试,可能会有没考虑到的地方
参考文献
《UNIX环境高级编程(第三版)》