写在前面

上传的作业代码与测试代码放在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. python3+spark2.1+kafka0.8+sparkStreaming

    python代码: import time from pyspark import SparkContext from pyspark.streaming import StreamingContex ...

  2. 好工具 VHD

    通过powershell 互转 Convert-VHD –Path F:\debian.vhdx –DestinationPath F:\debian.vhd 举个栗子 附加参考 Convert-VH ...

  3. 整合hibernate的lucene大数据模糊查询

      大数据模糊查询lucene 对工作单使用 like模糊查询时,实际上 数据库内部索引无法使用 ,需要逐条比较查询内容,效率比较低在数据量很多情况下, 提供模糊查询性能,我们可以使用lucene全文 ...

  4. devicetree -- SPI

    SPI (Serial Peripheral Interface) busses SPI busses can be described with a node for the SPI master ...

  5. 一个通用的JavaScript分页

    1.JavaScript代码 Pagination=function(id) { var totalNum=0; var maxNum=10; var pageUrl=""; va ...

  6. (转)FFMPEG-数据结构解释(AVCodecContext,AVStream,AVFormatContext)

    AVCodecContext  这是一个描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息 如果是单纯使用libavcodec,这部分信息需要调用者进行初始化:如果是使用整个FFMPEG库 ...

  7. 【NOIP模拟题】“与”(位运算)

    因为是与运算,所以我们可以贪心地每次找最高位的,将他们加入到新的序列中,然后每一次在这个新的序列继续找下一个位. 然后最后序列中任意两个的与运算的值都是一样的且是最大的. #include <c ...

  8. HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

    上一篇仅仅讲到前台操作,这篇专门涉及到Java后台处理.前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理.通过对图片数据信息进行Base64解码,之 ...

  9. 学习:java代码检测

    转自:http://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A0%81%E5%BC%82%E5%91%B3 对于Java开发语言,有些工具,比如Checkstyle.PM ...

  10. java中main方法的 (String []args)

    java中main方法的 (String []args)         String[] args是main函数的形式参数,可以用来获取命令行用户输入进去的参数.java 本身不存在不带String ...