需求是这样的。写出一个程序,模仿wc.exe,可以统计出文件的一些信息(比如字符数、单词数目等等)

对于这个程序,我仍然用我从大一学来的C语言写的。

第一步:打开文件

 printf("请输入文件名称");
scanf("%s", filename);
transName(filename, outputname);
if( ((fp = fopen(filename, "r")) == NULL) || ((output = fopen(outputname, "w")) == NULL) ){
printf("ERROR: 无法打开统计文件");
return ;
}

第二步:读取文件进行处理,这里我采用的是fgets函数来进行按行的读取。

fgets(content, , temp); //content: char[] 用来存放读取内容

第三步:对获取到的内容进行处理。

  a)获取内容字符数。这里将出空格换行以及tab以外的其他字符都计入统计。代码如下

 int charCounter(char *content) {
int lengh = strlen(content);
for (int i = ; i < strlen(content); i++)
{
if ( == content[i] || == content[i] || content[i] == '\t')
lengh--;
}
return lengh;
}

  b)获取单词数。这里明确,单词应以字母开头,以非字母、数字、点和下划线结尾。所以判断代码如下:

 bool IsChar(char c) { //判断首字母是否为英文字符
if ((c >= 'a'&&c <= 'z') || (c >= 'A'&&c <= 'Z'))
return true;
return false;
} bool IsRight(char c) { //用以判断单词结束
if (IsChar(c) || c == '.' || c == '_' || (c <= ''&&c >= ''))
return true;
return false;
} int wordCounter(char *content) {
int num = ;
int len = strlen(content);
for (int i = ; i < len; i++) {
if (IsChar(content[i])) {
while (i<len) {
if (!IsRight(content[i++]))
{
num++;
break;
}
}
}
}
return num;
}

  c)行数的判断运用到了字符数的判断,判断当这行内容字符数不为0时,为非空行。代码如下:

if (charCounter(content))
line++; //非空行计数+1
else
spaceline++; //空行计数+1

  d)注释行的判断,针对注释的两种情况,可以在传入内容时传入一个数字flag以确定状态(0:上文中无未结束的"/*" 1:上文中有未结束的"/*")。这样在判断注释行时,首先检察状态。当flag为0时,查找内容,如有"//"则注释行返回true,如有"/*"则将flag置1并返回true。否则,返回false;当flag为1时,只需查找内容中是否有"*/",如有,则置flag为0。这里返回值一定为true。代码如下:

 bool IsNoteline(char* content,int* flag) {  //flag 0:当前无多行注释 1:当前有多行注释
if (*flag) {
for (int i = ; i < strlen(content); i++) {
if (content[i] == '*' && content[i + ] == '\/')
{
*flag = ;
}
}
return true;
}else {
for (int i = ; i < strlen(content); i++)
{
if (content[i] == '\/') {
if (content[i + ] == '\/')
return true;
else if (content[i + ] == '*')
{
*flag = ;
return true;
}
}
}
return false;
}
}

第四步,格式化输出统计信息。这里采用文件及控制窗口两种方式输出。代码如下:

  a)输出文件名称的转换。(默认读取的文件为非txt格式)

  

 void transName(char *filename, char *outputname) {//转换文件名,存储统计文件
int i;
for (i = ; i < strlen(filename); i++) {
if (filename[i] == '.')
break;
outputname[i] = filename[i];
}
outputname[i] = '.';
outputname[++i] = 't';
outputname[++i] = 'x';
outputname[++i] = 't';
outputname[++i] = '\0'; }

  b)输出统计信息,以及将详细信息输出到文件里。

 while (!feof(temp)) {
fgets(content, , temp);
//printf("%d %s\n", charcounter(content), content);
fprintf(output, "\n\ncode:%schar:%d word: %d", content, charCounter(content), wordCounter(content));//统计信息输出到文件
if (charCounter(content))
line++;
else
spaceline++;
charnum += charCounter(content);
wordnum += wordCounter(content);
noteline += (IsNoteline(content, &flag) ? : );
}
fprintf(output, "\n\n----------统计数据汇总---------\n\n有效行:%d \n无效行: %d \n注释行: %d \n字符数: %d \n单词数: %d \n", line, spaceline, noteline, charnum, wordnum);
printf("\n有效行:%d \n无效行: %d \n注释行: %d \n字符数: %d \n单词数: %d \n", line, spaceline, noteline, charnum, wordnum);

注:效果截图如下,末尾处为源代码和测试文件 test.c:

 /*
@version 1.0
@author Coder Li
@description
This is a tool for count your code.
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h> void transName(char *filename, char *outputname) {//转换文件名,存储统计文件
int i;
for (i = ; i < strlen(filename); i++) {
if (filename[i] == '.')
break;
outputname[i] = filename[i];
}
outputname[i] = '.';
outputname[++i] = 't';
outputname[++i] = 'x';
outputname[++i] = 't';
outputname[++i] = '\0'; } int charCounter(char *content) {
int lengh = strlen(content);
for (int i = ; i < strlen(content); i++)
{
if ( == content[i] || == content[i] || content[i] == '\t')
lengh--;
}
return lengh;
} bool IsChar(char c) { //判断首字母是否为英文字符
if ((c >= 'a'&&c <= 'z') || (c >= 'A'&&c <= 'Z'))
return true;
return false;
} bool IsRight(char c) { //判断单词结束
if (IsChar(c) || c == '.' || c == '_' || (c <= ''&&c >= ''))
return true;
return false;
} int wordCounter(char *content) {
int num = ;
int len = strlen(content);
for (int i = ; i < len; i++) {
if (IsChar(content[i])) {
while (i<len) {
if (!IsRight(content[i++]))
{
num++;
break;
}
}
}
}
return num;
} bool IsNoteline(char* content,int* flag) { //flag 0:当前无多行注释 1:当前有多行注释
if (*flag) {
for (int i = ; i < strlen(content); i++) {
if (content[i] == '*' && content[i + ] == '\/')
{
*flag = ;
}
}
return true;
}else {
for (int i = ; i < strlen(content); i++)
{
if (content[i] == '\/') {
if (content[i + ] == '\/')
return true;
else if (content[i + ] == '*')
{
*flag = ;
return true;
}
}
}
return false;
}
} int main() {
FILE *fp, *temp, *output;
char filename[],outputname[];
char content[];
int line = , spaceline = , noteline = , flag = ;
//行数统计 line:有效行 spaceline:无效行 noteline:含注释的行 flag:注释行标记
int charnum = ;//字符数统计
int wordnum = ; //单词数统计 printf("请输入文件名称");
scanf("%s", filename);
transName(filename, outputname);
if( ((fp = fopen(filename, "r")) == NULL) || ((output = fopen(outputname, "w")) == NULL) ){
printf("ERROR: 无法打开统计文件");
return ;
} temp = fp;
fprintf(output, "文件名:%s\n", filename);
while (!feof(temp)) {
fgets(content, , temp);
//printf("%d %s\n", charcounter(content), content);
fprintf(output, "\n\ncode:%schar:%d word: %d", content, charCounter(content), wordCounter(content));//统计信息输出到文件
if (charCounter(content))
line++;
else
spaceline++;
charnum += charCounter(content);
wordnum += wordCounter(content);
noteline += (IsNoteline(content, &flag) ? : );
}
fprintf(output, "\n\n----------统计数据汇总---------\n\n有效行:%d \n无效行: %d \n注释行: %d \n字符数: %d \n单词数: %d \n", line, spaceline, noteline, charnum, wordnum);
printf("\n有效行:%d \n无效行: %d \n注释行: %d \n字符数: %d \n单词数: %d \n", line, spaceline, noteline, charnum, wordnum);
printf("\n\n详细信息请看当前目录下同名txt文件\n输入任意数字结束程序\n");
scanf("%d", &charnum);
fclose(fp);
fclose(output);
return ;
}

源码

 /*
@version 1.1
@author Coder Li
@description This is a tool for your code.*/ #include<stdio.h>
#include<string.h>
#include<stdlib.h> bool IsNoteline(char* content,int* flag) { //flag 0:当前无多行注释 1:当前有多行注释,找不到多行注释
for (int i = ; i < strlen(content); i++)
{
if (!(*flag)) {
if (content[i] == '\/') {
if (content[i + ] == '\/')
return true;
else if (content[i + ] == '*')
{
*flag = ;
return true;
}
}
}
else {
if (content[i] == '*' && content[i + ] == '\/')
{
*flag = ;
return true;
}
}
}
return false;
} bool IsChar(char c) {
if ((c >= 'a'&&c <= 'z')||(c>='A'&&c<='Z'))
return true;
return false;
} bool IsRight(char c) {
if (IsChar(c) || c == '.' || c == '_' || (c <= ''&&c >= ''))
return true;
return false;
} int charcounter(char *content) {
int lengh = strlen(content);
for (int i = ; i < strlen(content); i++)
{
if ( == content[i] || == content[i] || content[i] == '\t')
lengh--;
}
return lengh;
} int wordcounter(char *content) {
int num = ;
int len = strlen(content);
for (int i = ; i < len; i++) {
if (IsChar(content[i])) {
while(i<len){
if (!IsRight(content[i++]))
{
num++;
break;
}
}
}
}
return num;
} int main() {
FILE *fp, *temp, *output;
char filename[];
char content[];
int line = , spaceline = , noteline = , flag = ; //行数统计 line:有效行 spaceline:无效行 noteline:含注释的行 flag:注释行标记
int charnum = ;//字符数统计
int wordnum = ; //单词数统计
output = fopen("output.txt", "w");
printf("请输入文件名称");
scanf("%s", filename);
if ((fp = fopen(filename, "r")) == NULL) {
printf("ERROR: 无法打开文件");
return ;
}
while (!feof(fp)) {
fgets(content, , fp);
fprintf(fp,"%d%s", charcounter(content), content);
printf("%d\t%s\n", charcounter(content), content);
if (charcounter(content))
line++;
else
spaceline++;
charnum += charcounter(content);
wordnum += wordcounter(content); noteline += IsNoteline(content, &flag) ? : ;
}
printf("\n有效行:%d \n无效行:%d \n注释行:%d \n字符数: %d \n单词数: %d \n", line, spaceline, noteline, charnum, wordnum);
scanf("%d", &charnum);
return ;
}

test.c

第三周作业(三)---WordCounter的更多相关文章

  1. JAVA第三周作业(从键盘输入若干数求和)

    JAVA第三周作业(从键盘输入若干数求和) 在新的一周,我学习了JAVA的IO编程.下面的代码实现了从键盘输入若干数求和的目标.import java.util.Scanner; public cla ...

  2. 第三周作业、实时操作系统µC/OS介绍及其它内容

    作业要求 见<实时控制软件设计>第三周作业 1 阅读笔记--µC/OS 1.1 基本介绍 µC/OS是由Micrium公司研发的实时操作系统,以µC/OS-II或µC/OS-III为内核, ...

  3. 2018-2019-1 20189221《Linux内核原理与分析》第三周作业

    2018-2019-1 20189221<Linux内核原理与分析>第三周作业 实验二 完成一个简单的时间片轮转多道程序内核代码 实验过程 在实验楼中编译内核 编写mymain.c函数和m ...

  4. 2017-2018-2 1723《程序设计与数据结构》第三周作业 & 实验一 总结

    作业地址 第三周作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1667 提交情况如图: 实验一:https://edu.c ...

  5. 第三周作业(一)VS安装及单元测试练习

    第三周作业(一) 需求:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂,没 ...

  6. 2017-2018-1 JaWorld 第三周作业

    2017-2018-1 JaWorld 第三周作业 团队展示 队员学号 队名 团队项目描述 队员风采 团队的特色 团队合照 团队初步合作 前两周的反思与总结 需要改进的地方 团队选题 *采访老师或有开 ...

  7. 2017-2018-1 JAVA实验站 第三周作业

    2017-2018-1 JAVA实验站 第三周作业 团队展示 队名 JAVA实验站 拟作的团队项目描述 (2048)增加其他模式,使得2048更加丰富多彩 团队的首次合照 团队的特色描述 团队内部很团 ...

  8. 2017-2018-1 20179205《Linux内核原理与设计》第三周作业

    <Linux内核原理与分析>第三周作业 教材学习总结 第三章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,是正在执行的程序代码的实时结果:线程,是在进程中活动的对象.而Linu ...

  9. 第三周作业-课本&&视频学习

    <网络攻防技术与实践>第三周作业 Part I 寻找自己留在互联网上的足迹并消除隐私 1.1 google/baidu搜索自己的qq号 搜索结果如图,搜到的有用信息其实就是图上这么几条,能 ...

  10. 2019-2020-1 20199329《Linux内核原理与分析》第三周作业

    <Linux内核原理与分析>第三周作业 一.上周问题总结: 第二周头脑风暴完成较慢 虚拟机libc配置错误 书本知识使用不够熟练 二.本周学习内容: 1.实验楼环境虚拟一个x86的CPU硬 ...

随机推荐

  1. 使用虚拟环境virtualenv/Virtualenvwrapper隔离多个python

    virtualenv 系统中的多个python混用会导致$PYTHONPATH混乱,或者各个工程对于package的版本要求不同等等情况.有一个简单的解决方案就是用virtualenv来隔离多个pyt ...

  2. 【PAT】B1072 开学寄语(20 分)

    代码注释应该很清晰 先存下违禁品,放到数组中,未使用map #include<cstdio> #include<string.h> int wupin[10],N,M; boo ...

  3. C# show和showdialog区别

    简单地说他们的区别就是show弹出来的窗体和父窗体(上一个窗体的简称)是属于同一等级的,这两个窗体可以同时存在而且可以随意切换,但是showdialog弹出来的窗体就不能这样,他永远是被置顶的,如果不 ...

  4. Shell的基础介绍和案例

    一.shell脚本基础 1.第一个脚本 vim  first.sh 分别使用三种方法可以执行脚本:   ./first.sh (需要有可执行的权限)   sh    first.sh   .  fir ...

  5. linux网关设置

    1.linux中eth0为外网ip.外网网关.外网DNS设置,eth1为内网ip”172.22.0.0/16“不设置网关.DNS. 2.启动linux内核中的IP转发功能 执行vim命令编辑sysct ...

  6. 个人技术博客(α)------javaweb的学习路程

    该博文大致内容是学习的一个过程,心得,并不是以技术博客为主,在此说明. 关于javaweb的学习开始的时间大概是从大二下(2017年6.7月份)的暑假开始的,在学长的介绍下加入了实验室进行学习,由于是 ...

  7. python3编写网络爬虫13-Ajax数据爬取

    一.Ajax数据爬取 1. 简介:Ajax 全称Asynchronous JavaScript and XML 异步的Javascript和XML. 它不是一门编程语言,而是利用JavaScript在 ...

  8. python scrapy爬虫框架概念介绍(个人理解总结为一张图)

    python的scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架   python和scrapy的安装就不介绍了,资料很多 这里我个人总结一下,能更加快理解scrapy和快速上手一个简 ...

  9. GUI_鼠标事件

    所有的组件都有鼠标和键盘监听器 import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; import ja ...

  10. c++引用lib和dll的方法总结

    C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  LIB文件直接加入到工程文件列表中 在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中"Add F ...