写在前面

上传的作业代码与测试代码放在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的原因写得比较匆忙,所用时间较少

    - 预估耗时是六个该项作业的估计时间,实际上有很多其他事情要处理,并没有留下这么多时间,也就是说其他的事情通过尽量压缩来尽量满足预留时间。

设计思路

  1. 实现将数据写入指定文件,读取指定文件的数据并输出
  2. 实现读取指定文件的行数,字符数,单词数并直接输出
  3. 从用户输入的字符串中提取相应的处理字,文件名并直接输出
  4. 将提取到的关键字与之前实现的功能进行对接
  5. 测试程序的一般情况与临界情况

程序分析

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

没有写测试脚本,但测试均可通过,表示基本功能没有问题

不足

除了扩展功能和高级功能没有完成外,有以下几个不足

  1. 生成的result.txt和outut.txt由于没有在程序内部进行清空,会导致在多次运行后,文件内部信息比较杂乱
  2. 默认先-c-w-l读取文件,再-o保存数据,因此无法在二者翻转时进行正确执行,但由于需求内没有标明,没有考虑该种情况,希望老师验收时注意
  3. 有多个功能聚集在主函数内部,比较杂乱,没有比较好的代码优化。

收获

本次作业除了加强编程能力外,让我们对时间安排有了更充分的理解,理解了上课所学习的基本内容,初步理解的测试的相关方法,希望能在今后的学习中对软件测试有更加深刻的理解和学习

wordcount(C语言)的更多相关文章

  1. WordCount C语言实现求文本的字符数,单词数,行数

    1.码云地址: https://gitee.com/miaomiaobobo/WordCount 2.psp表格 PSP2.1表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) P ...

  2. 个人项目(WordCount C语言)

    WordCount程序(C语言) Github地址:https://github.com/peter-ye-code/WordCount 一.题目描述 实现一个简单而完整的软件工具(源程序特征统计程序 ...

  3. 软件工程-wordcount(C语言实现)

    Github项目地址:https://github.com/xiaobaot/wordcount-wc/tree/master WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数 ...

  4. WordCount:C语言实现

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

  5. 结对编程项目——C语言实现WordCount Web化

    结对编程项目 代码地址 201631062219,201631011410 gitee项目地址:https://gitee.com/xxlznb/pair_programming 作业地址:https ...

  6. Scala,Java,Python 3种语言编写Spark WordCount示例

    首先,我先定义一个文件,hello.txt,里面的内容如下: hello sparkhello hadoophello flinkhello storm Scala方式 scala版本是2.11.8. ...

  7. Spark源码编译并在YARN上运行WordCount实例

    在学习一门新语言时,想必我们都是"Hello World"程序开始,类似地,分布式计算框架的一个典型实例就是WordCount程序,接触过Hadoop的人肯定都知道用MapRedu ...

  8. 软件工程-构建之法 WordCount小程序 统计文件中字符串个数,单词个数,词频,行数

    一.前言 在之前写过一个词频统计的C语言课设,别人说你一个大三的怎么写C语言课程,我只想说我是先学习VB,VB是我编程语言的开始,然后接触到C语言及C++:再后来我是学习C++,然后反过来学习C语言, ...

  9. 利用Scala语言开发Spark应用程序

    Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...

随机推荐

  1. tortoiseGit 如何github提交代码

    由于一直用的都是SVN提交代码,Git也是目前自己边学边用的,本来以为自己已经会用了,可是一段时间没用又忘了 ,所以赶紧整理整理记下来,以便日后使用! 转自:http://blog.csdn.net/ ...

  2. Vs code 通用插件

    Vs code 通用插件 转自:https://segmentfault.com/a/1190000006697219 HTML Snippets 超级实用且初级的 H5代码片段以及提示 HTML C ...

  3. cocos2d-x中CCEditbox导出到lua

    自从工作后感觉时间较少(每天工作9-22,晚上就不想动了,早上想多睡点),工作中用的是 cocos2d-x.cocos2d-x是一款手机游戏引擎,虽然支持lua,但和love2d相比非纯lua游戏引 ...

  4. Linux(centOS)手动安装删除Apache+MySQL+PHP+Memcached原创无错版

    =================== 第一步:Apache安装 =================== 下载 去 http://www.apache.org 自己找最新的 国内有很多镜像点例如人人和 ...

  5. 举例说明:Hadoop vs. NoSql vs. Sql vs. NewSql

    转自:http://blog.jobbole.com/86269/   尽管层次数据库如今在大型机上依然被广泛使用,但关系数据库(RDBMS)(SQL)已经占领了数据库市场,并且表现的相当优异.我们存 ...

  6. 如何创建Cookie? (选择1项)

    如何创建Cookie? (选择1项) A. 使用new Cookie语句 B. 调用response.addCookie方法 C. 使用Cookie的setMaxAge方法 D. setCookie方 ...

  7. jQuery学习笔记2——表单操作

    一.获取和设置表单的值:val()和text() 1. 获取表单的值: $("#username").val(); 2. 设置表单的值: $("#username&quo ...

  8. C语言0长度数组(柔性数组)

    0长度数组,又称为柔性数组(flexible array).通经常使用来实现变长数组.常见于TLV(type-length-value)的数据结构中. 在标准 C 和 C++ 中,不同意用 0 长度数 ...

  9. XMPP客户端

    1. Strophe.js 2. Converse.js

  10. 我在Facebook学到的10个经验

    1.坚持你的远景,但要对细节灵活. 作为一个领导者,你需要依赖你自己的远景(至少在你负责的业务领域内)而那些和你一起或为你工作的人将依赖你的远见.什么是远景?就是对最终状态的一种描述.是你需要你的团队 ...