wordcount(C语言)
写在前面
上传的作业代码与测试代码放在GitHub上了 https://github.com/IHHHH/gitforwork
本次作业用的是C语言来完成,因为个人能力与时间关系,只完成了基本功能,扩展功能和高级功能很遗憾没有完成。
基本功能
wc.exe -c file.c //返回文件 file.c 的字符数
wc.exe -w file.c //返回文件 file.c 的单词总数
wc.exe -l file.c //返回文件 file.c 的总行数
wc.exe -o outputFile.txt //将结果输出到指定文件outputFile.txt
PSP表格
- 关于预估耗时比实际耗时多的原因,并不是因为能力比预估的高,而是一下几点原因:
- 预估耗时是以完成除高级功能外所有功能,包括基本功能和扩展功能,而实际任务中,并没有实现扩展功能,仅仅完成了基本功能
- 完成较少的功能代表着需要较少的时间来学习新的函数和语法
- 报告因为ddl的原因写得比较匆忙,所用时间较少
- 预估耗时是六个该项作业的估计时间,实际上有很多其他事情要处理,并没有留下这么多时间,也就是说其他的事情通过尽量压缩来尽量满足预留时间。
设计思路
- 实现将数据写入指定文件,读取指定文件的数据并输出
- 实现读取指定文件的行数,字符数,单词数并直接输出
- 从用户输入的字符串中提取相应的处理字,文件名并直接输出
- 将提取到的关键字与之前实现的功能进行对接
- 测试程序的一般情况与临界情况
程序分析
char* t; //result
char* wr; //output
char a[50]; //记录输入数据
char b[50]; //记录读取的文件地址
char WC[1000]; //保存打开的文件内容
int col_count(const char* t); //统计字符数
int col_row(const char* t); //统计行数
int col_word(const char* t); //统计单词数
void result(const char* t, const char* a, int num); //产生结果文件
void output(const char* t, const char* w, int count, int row, int word);//产生输出文件
通过两个指针记录可能出现的两个文件地址字符串的首地址,为了简便,b数组中相应数据的位置与a相同,通过指针进行读取。
for (int i = 0; a[i] != NULL; i++)
{
if(a[i] == '-')
if (a[i+1] == 'o')
for (int j = i+1; a[j] != NULL; j++)
{
if (a[j] == ' ')
if (a[j + 1] != ' '&&a[j + 1] != '-') //输出文件入口判断
{
wr = a + j + 1;
break;
}
}
}
通过对输入信息的判断来提取代表文件地址的字符串
for (int i = 1; a[i] != NULL; i++)
{
if (a[i - 1] == ' ')
if (a[i] != ' '&&a[i] != '-') //目标文件名入口判断
{
int j = i;
while (a[i] != ' '&&a[i] != NULL) //目标文件名出口判断
{
b[i] = a[i];
i++;
}
t = b + j;
break;
}
}
默认读取的文件在需要写入的文件前,因此读取的文件判断相对复杂,需要对入口和出口同时进行判断
if(a[i] == '-')
{
if (a[i + 1] == 'c')
{
count = col_count(t);
printf_s("字符数:%d", count);
result(t, "字符数", count);
printf_s("\n");
}
if (a[i + 1] == 'l')
{
row = col_row(t);
printf_s("行数:%d", row);
result(t, "行数", row);
printf_s("\n");
}
if (a[i + 1] == 'w')
{
word = col_word(t);
printf_s("单词数:%d", word);
result(t, "单词数", word);
printf_s("\n");
}
if (a[i + 1] == 'o')
{
output(t, wr, count, row, word);
printf_s("\n");
}
}
通过“-”后面的不同情况应用不同的函数
int col_count(const char* t)
{
char data;
FILE *fp;
errno_t err;
int count = 0;
err = fopen_s(&fp, t, "r");
if (err != 0)
{
printf("can't open file\n");
count = -1;
}
while ((data = getc(fp)) != EOF)
{
WC[count] = data;
count++;
}
fclose(fp);
return count;
}
int col_row(const char* t)
{
char data;
FILE *fp;
errno_t err;
int row = 0;
err = fopen_s(&fp, t, "r");
if (err != 0)
{
printf("can't open file\n");
row = -1;
}
while ((data = getc(fp)) != EOF)
if (data == '\n')
row++;
fclose(fp);
return row;
}
int col_word(const char* t)
{
char data;
FILE *fp;
errno_t err;
int word = 0;
int i = 0;
err = fopen_s(&fp, t, "r");
if (err != 0)
{
printf("can't open file\n");
word = -1;
}
while ((data = getc(fp)) != EOF)
{
WC[i] = data;
i++;
}
if (WC[0] != ' ' && WC[0] != ',' && WC[0] != '\n')
word++;
for (i = 0; WC[i] != NULL; i++)
{
if (WC[i] == ' ' || WC[i] == ',' || WC[i] == '\n')
if (WC[i + 1] != ' ' && WC[i + 1] != ',' && WC[i + 1] != '\n')
word++;
}
fclose(fp);
return word;
}
以上三个函数为需要实现功能函数,均用getc()函数对文件按照一个字符一个字符的方式读取,不同的是自变量的递增条件
判断字符数时,每读取一个就加1,初值为0
判断行数时,每读取一个换行符加1,初值为1
判断单词数时,进行单词的开头与结尾判断,每对应一次加一,但根据判断条件不同,有时要加上开头或者结尾的一个单词
void result(const char* t, const char* a, int num)
{
FILE *wt;
errno_t err;
err = fopen_s(&wt, "result.txt", "a+");
if (err != 0)
{
printf("can't write file\n");
}
fprintf(wt, "%s,%s:%d\n", t, a, num);
fclose(wt);
}
void output(const char* t, const char* w, int count, int row, int word)
{
FILE *wt;
errno_t err;
err = fopen_s(&wt, w, "a+");
if (err != 0)
{
printf("can't write file\n");
}
fprintf(wt, "%s,字符数:%d,行数:%d,单词数:%d", t, count, row, word);
fclose(wt);
}
写文件函数,a+表示不擦除之前所写的内容,且去掉之前的停止符EOF
测试
测试思路
测试要覆盖可能出现的左右情况,尽量找到代码中可能蕴含的错误并改正,因此,测试设计应该覆盖判断中的各种边界情况,,满足基本功能的所有需求,-c –w –l -o
用于测试的输入
-c test.txt
-w test.txt
-l test.txt
-c –w test.txt
-c –l test.txt
-w –l test.txt
-c –w –l test.txt
-c test.txt –o output.txt
-w test.txt –o output.txt
-l test.txt –o output.txt
-c –w test.txt –o output.txt
-c –l test.txt –o output.txt
-w –l test.txt –o output.txt
-c –w –l test.txt –o output.txt
没有写测试脚本,但测试均可通过,表示基本功能没有问题
不足
除了扩展功能和高级功能没有完成外,有以下几个不足
- 生成的result.txt和outut.txt由于没有在程序内部进行清空,会导致在多次运行后,文件内部信息比较杂乱
- 默认先-c-w-l读取文件,再-o保存数据,因此无法在二者翻转时进行正确执行,但由于需求内没有标明,没有考虑该种情况,希望老师验收时注意
- 有多个功能聚集在主函数内部,比较杂乱,没有比较好的代码优化。
收获
本次作业除了加强编程能力外,让我们对时间安排有了更充分的理解,理解了上课所学习的基本内容,初步理解的测试的相关方法,希望能在今后的学习中对软件测试有更加深刻的理解和学习
wordcount(C语言)的更多相关文章
- WordCount C语言实现求文本的字符数,单词数,行数
1.码云地址: https://gitee.com/miaomiaobobo/WordCount 2.psp表格 PSP2.1表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) P ...
- 个人项目(WordCount C语言)
WordCount程序(C语言) Github地址:https://github.com/peter-ye-code/WordCount 一.题目描述 实现一个简单而完整的软件工具(源程序特征统计程序 ...
- 软件工程-wordcount(C语言实现)
Github项目地址:https://github.com/xiaobaot/wordcount-wc/tree/master WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数 ...
- WordCount:C语言实现
项目地址:https://github.com/m8705/WordCount 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数. 这个项目要求写一个命令行程序,模仿已 ...
- 结对编程项目——C语言实现WordCount Web化
结对编程项目 代码地址 201631062219,201631011410 gitee项目地址:https://gitee.com/xxlznb/pair_programming 作业地址:https ...
- Scala,Java,Python 3种语言编写Spark WordCount示例
首先,我先定义一个文件,hello.txt,里面的内容如下: hello sparkhello hadoophello flinkhello storm Scala方式 scala版本是2.11.8. ...
- Spark源码编译并在YARN上运行WordCount实例
在学习一门新语言时,想必我们都是"Hello World"程序开始,类似地,分布式计算框架的一个典型实例就是WordCount程序,接触过Hadoop的人肯定都知道用MapRedu ...
- 软件工程-构建之法 WordCount小程序 统计文件中字符串个数,单词个数,词频,行数
一.前言 在之前写过一个词频统计的C语言课设,别人说你一个大三的怎么写C语言课程,我只想说我是先学习VB,VB是我编程语言的开始,然后接触到C语言及C++:再后来我是学习C++,然后反过来学习C语言, ...
- 利用Scala语言开发Spark应用程序
Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...
随机推荐
- dubbo异步调用三种方式
异步通讯对于服务端响应时间较长的方法是必须的,能够有效地利用客户端的资源,在dubbo中,消费端<dubbp:method>通过 async="true"标识. < ...
- C++函数默认参数(转)
在代码中使用到了函数的默认参数,在函数的定义和实现中都填写的默认参数,结果出现了错误: 代码: #ifndef FIRSTPAGE_H #define FIRSTPAGE_H #include < ...
- 安装语言包(LANGUAGE PACKAGE)
by 枫竹丹青 一.说明 在SAP ECC 安装好后,如果是生产版本,通常只有两种语言--英语和德语.这时如需中文环境,则需定义支持的语言类型并导入语言包.如果安装的是IDES版,则系统中已包含了几十 ...
- jq判断元素class是否定义了CSS样式
if($("div").attr("class")==null) 如果$("div").attr("class")为空, ...
- 替换元素节点replaceChild()
替换元素节点replaceChild() replaceChild 实现子节点(对象)的替换.返回被替换对象的引用. 语法: node.replaceChild (newnode,oldnew ) 参 ...
- php服务器环境变量
可以把一些配置写到apache或nginx的配置里,然后在代码里判断环境变量来实现开发环境和线上环境的切换. 比如在本地可以 SetEnv APP_ENV local线上则 SetEnv APP_EN ...
- lua工具库penlight--04路径和目录
使用路径 程序不应该依赖于奇葩的系统,这样你的代码会难以阅读和移植.最糟糕的是硬编码的路径, windows和Unix的路径分隔符正好相反.最好使用path.join,它可以帮助你解决这个问题. pl ...
- EAGAIN、EWOULDBLOCK、EINTR与非阻塞 长连接
EAGAIN.EWOULDBLOCK.EINTR与非阻塞 长连接 EWOULDBLOCK用于非阻塞模式,不需要重新读或者写 EINTR指操作被中断唤醒,需要重新读/写 在Linux环境下开发经常会碰到 ...
- mysql中创建用户和赋权限
mysql命令行用的不多,大部分使用工具类替代,所以这里记录下命令行模式下创建用户和赋予权限的命令,不用每次麻烦百度. 1. 创建oozie用户,%符号表示仅限于远程登录 create user 'o ...
- 轻量级分布式 RPC 框架(转)
RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. RPC 可基于 HTTP 或 TCP 协议,Web Servi ...