第一次作业

项目地址

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环境高级编程(第三版)》

程序实现过程

程序分为两个主要步骤在主函数中我们只需要调用这两个函数

  1. 解析参数

    解析参数,我把参数分为三类,短选项、长选项、文件名,

    • 短参数,以-开始后紧跟一个字符,短参数可以叠加使用,也可以单独使用,例如 -c -l -w
    • 长参数,短参数在使用频繁的时候可能造成输入麻烦,因此,你可以将短参数直接写在一个-后,例如 -c -l -w [file] 可直接简写为-clw [file] 顺序和内容都自由更改
    • 文件名称,文件名称位于参数后,且如果没有参数则会报错,如果一个参数后紧跟多个文件名,则对多个文件执行同等的操作,例如 -clw [file1] [file2] ,但-o参数除外,-o只能指定一个文件

    对于参数解析采取宽容方式 -c -c [file] 重复参数不报错。

    具体做法为构造一个解析链表,将解析结果存入链表中

    同时将执行模式存入其中,为了节约储存空间,将模式直接放入一个int中,之后判断int的位就可以知道它的模式

  2. 统计内容

    统计内容为了方便添加功能,将每个功能单独写一个函数,之后调用函数即可。

代码说明

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环境高级编程(第三版)》

wc基础功能的更多相关文章

  1. 通过python实现wc基本功能

    ---恢复内容开始--- 1.Github项目地址: https://github.com/zhg1998/ww/blob/master/wc.py 2.项目相关要求: 写一个命令行程序,模仿已有wc ...

  2. C语言实现wc基本功能

    GitHub地址:https://github.com/hhx007/wc 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数. 这个项目要求写一个命令行程序,模仿已有w ...

  3. [ kvm ] 学习笔记 3:KVM 基础功能详解

    1. 构建 KVM 环境 KVM 从诞生开始就需要硬件虚拟化的支持,KVM 必需的硬件虚拟化扩展分别是:Intel 的虚拟化技术(Intel VT)和 AMD 的 AMD-V 技术.首先处理器(CPU ...

  4. 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.0,完善基础功能(源码)

    (前段时间封闭式开发完了一个项目,最近才有时间继续更新GG的后续版本,对那些关注GG的朋友来说,真的是很抱歉.)GG的前面几个版本开发了一些比较高级的功能,像视频聊天.远程桌面.文件传送.远程磁盘等, ...

  5. 谷歌Chrome浏览器开发者工具的基础功能

    上一篇我们学习了谷歌Chrome浏览器开发者工具的基础功能,下面介绍的是Chrome开发工具中最有用的面板Sources.Sources面板几乎是最常用到的Chrome功能面板,也是解决一般问题的主要 ...

  6. Netsharp快速入门(之16) Netsharp基础功能(权限管理)

    第5章     Netsharp基础功能 5.1     权限配置 5.1.1  功能权限 1.配置权限功能点,打开平台工具-基础业务-操作管理 2.选择资源节点为销售订单,点添加常用操作,添加完成后 ...

  7. 李洪强iOS开发之-环信03_集成 SDK 基础功能

    李洪强iOS开发之-环信03_集成 SDK 基础功能 集成 SDK 基础功能 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. SDK 同步/异步方法区分 ...

  8. Keepalived详解(三):Keepalived基础功能应用实例【转】

    Keepalived基础功能应用实例: 1.Keepalived基础HA功能演示: 在默认情况下,Keepalived可以实现对系统死机.网络异常及Keepalived本身进行监控,也就是说当系统出现 ...

  9. jmeter 基础功能详解

    jmeter 基础功能详解 thread group:包含一组线程,每个线程独立地执行测试计划. sampler:采样器,有多种不同的sample实现,用来发起各种请求,如http请求,jdbc请求, ...

随机推荐

  1. [Java]LeetCode284. 顶端迭代器 | Peeking Iterator

    Given an Iterator class interface with methods: next() and hasNext(), design and implement a Peeking ...

  2. [Swift]LeetCode907. 子数组的最小值之和 | Sum of Subarray Minimums

    Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarra ...

  3. java集合框架整理

    一.总体框架 Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.* .Java集合主要可以划分为4个部分:Lis ...

  4. Java面试题:小白不得不懂的斐波那契数列

    很长一段时间里,我都非常疑惑:“我写的技术文章不差啊,有内容的同时还很有趣,不至于每篇只有区区几十个人读啊?为什么有些内容简单到只有一行注册码的文章浏览量反而轻松破万?”这样的疑惑如鲠在喉啊!写技术博 ...

  5. .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现

    本篇我将带着大家一起来对Dapper进行下封装并实现基本的增删改查.分页操作的同步异步方法的实现(已实现MSSQL,MySql,PgSQL).同时我们再实现一下仓储层的代码生成器,这样的话,我们只需要 ...

  6. MVC中的下载文件及上传

    前言:最近做的项目中用到了文件下载与上传,一下子想不起来,只能进行百度,为了方便自己做了一个小demo,特此写了这篇小笔记 1.页面方面: 2.控制器方面 namespace MvcUpload.Co ...

  7. Java开发需掌握的常用Linux命令(持续更新)

    linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命 ...

  8. 带着萌新看springboot源码11(springboot启动原理 源码上)

    通过前面这么多讲解,springboot原理应该也大概有个轮廓了,一些基本的配置,从客户端url到controller(配置一些要用的组件,servlet三大组件,处理器映射器,拦截器,视图解析器这些 ...

  9. Python进阶:自定义对象实现切片功能

    2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...

  10. 深度学习入门实战(一):像Prisma一样算法生成梵高风格画像

    本文由云+社区发表 作者:董超 导语:现在人工智能是个大热点,而人工智能离不开机器学习,机器学习中深度学习又是比较热门的方向,本系列文章就从实战出发,介绍下如何使用MXnet进行深度学习~ 既然是实战 ...