源统计程序(WordCount)
GitHub地址:https://github.com/CloudDawnSun/WC
一.项目要求
1. wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
2. 实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] [file_name]
二.解题思路
本来我打算用新学的Java来实现功能,经过尝试过后放弃了,因为我对Java的接口调用和文件操作太不熟悉了。
统计字符数和行数直接就通过fgetc()函数获取标志字符进行判断,而单词我则将英语字符串定义为单词
三.代码
#include<stdio.h>
#include<string.h>
#include<io.h>
#include<stdlib.h>
#define MAXSIZE 1024
//统计字符数
void countchar(char* filename)
{
char c;
int charnum = 0;
FILE* fp;
fp = fopen(filename, "r");
if (fp == NULL)
{
printf("打开文件失败或文件不存在\n");
}
else
{
c = fgetc(fp);
while (c != EOF)
{
charnum++;
c = getc(fp);
}
printf("字符数:%d\n", charnum);
fclose(fp);
}
}
1 //统计文件行数
2 void countline(char* filename)
3 {
4 FILE* fp;
5 int linenum = 0;
6 char c;
7 fp = fopen(filename, "r");
8 if (fp == NULL)
9 {
10 printf("打开文件失败或文件不存在");
11 return;
12 }
13 c = fgetc(fp);
14 if (c != EOF) linenum++;
15 while (c != EOF)
16 {
17 if (c == ‘\n‘ || c == ‘\r‘)
18 linenum++;
19 c = fgetc(fp);
20 }
21 printf("行数:%d\n", linenum);
22 fclose(fp);
23 }
//统计词数,一个字母算作一个单词
void countword(char* filename)
{
int wordnum = 0;
char c;
int judge = 0;
FILE* fp;
fp = fopen(filename, "r");
if (fp == NULL)
{
printf("打开文件失败或文件不存在");
return;
}
c = fgetc(fp);
while (c != EOF)
{
if ((c >= ‘a‘ && c <= ‘z‘) || (c >= ‘A‘ && c <= ‘Z‘))
{
judge = 1; //记录前一个字符是不是字母
}
else
judge = 0;
c = fgetc(fp);
if (c == EOF) break;
if (!((c >= ‘a‘ && c <= ‘z‘) || (c >= ‘A‘ && c <= ‘Z‘)))
if (judge == 1)
wordnum++;
}
if (judge == 1)
wordnum++;
printf("词数:%d\n", wordnum);
fclose(fp);
}
//统计空行和代码行
void countSline(char* filename)
{
int spaceline = 0; //空行
int codeline = 0; //代码行
char c;
int jnull=1; //标志此行是不是空行
FILE* fp;
fp = fopen(filename, "r");
if (fp == NULL)
{
printf("文件打开失败或文件不存在");
return;
}
do
{
c = fgetc(fp);
if (c == ‘\n‘)
{
if (jnull == 1) spaceline++;
else codeline++;
jnull = 1; //每一行开始时默认为空行
}
if (c != ‘ ‘ && c != ‘\n‘ && c != ‘\r‘&&c!=-1) //不是空格或换行或文件末尾,则不是空行
jnull = 0;
} while (!feof(fp));
if (jnull == 1) spaceline++; //最后一行判断(没有换行符要独立判断)
else codeline++;
printf("代码行:%d\n", codeline);
printf("空行:%d\n", spaceline);
fclose(fp);
}
//输入 目录时调用此函数处理目录下文件
void findFiles(char* Path, char* choose[], int argc)
{
intptr_t judgePath; //文件句柄,相当与文件指针fp,用于判断是否路径是否存在
_finddata_t File;
int i = 1;
FILE* fp; //用于判断是否是统计对象
char strfind[MAXSIZE]; //用于加通配符,寻找文件
char str[MAXSIZE]; //用于记录文件路径
strcpy(strfind, Path);
strcat(strfind, "\\");
strcat(strfind, "*.*"); // 在要遍历的目录后加上通配符
judgePath = _findfirst(strfind, &File); // 查找目录中的第一个文件
if (judgePath == -1)
{
printf("文件路径错误或不存在\n");
return;
}
do
{
if (File.attrib & _A_SUBDIR
&& strcmp(File.name, ".") == 0
&& strcmp(File.name, "..") == 0
);
else
{
strcpy(str, Path);
strcat(str, "\\");
strcat(str, File.name);
if ((fp = fopen(str, "r")) != NULL)
{
printf("%s\n", str);
for (i = 1; i < argc - 1; i++)
{
if (strcmp(choose[i], "-c") == 0)
countchar(str);
if (strcmp(choose[i], "-l") == 0)
countline(str);
if (strcmp(choose[i], "-w") == 0)
countword(str);
}
}
}
} while (_findnext(judgePath, &File) == 0); // 查找下一个文件
_findclose(judgePath); // 关闭句柄
}
int main(int argc, char* argv[])
{
int i = 1;
FILE* fp;
fp = fopen(argv[argc - 1], "r");
if (fp == NULL)
{
findFiles(argv[argc - 1], argv, argc);
}
else
{
for (i = 1; i < argc - 1; i++)
{
if (strcmp(argv[i], "-c") == 0)
countchar(argv[argc - 1]);
if (strcmp(argv[i], "-l") == 0)
countline(argv[argc - 1]);
if (strcmp(argv[i], "-w") == 0)
countword(argv[argc - 1]);
if (strcmp(argv[i], "-a") == 0)
{
countSline(argv[argc - 1]);
countnoteline(argv[argc - 1]);
}
}
fclose(fp);
}
return 0;
}
四. 运行结果





五. PSP
PSP2.1
|
Personal Software Process Stages
|
预估耗时(分钟)
|
实际耗时(分钟)
|
Planning
|
计划
|
60
|
60
|
· Estimate
|
· 估计这个任务需要多少时间
|
300
|
400
|
Development
|
开发
|
200
|
300
|
· Analysis
|
· 需求分析 (包括学习新技术)
|
100
|
200
|
· Design Spec
|
· 生成设计文档
|
20
|
20
|
· Design Review
|
· 设计复审 (和同事审核设计文档)
|
15
|
15
|
· Coding Standard
|
· 代码规范 (为目前的开发制定合适的规范)
|
20
|
20
|
· Design
|
· 具体设计
|
60
|
65
|
· Coding
|
· 具体编码
|
120
|
200
|
· Code Review
|
· 代码复审
|
20
|
20
|
· Test
|
· 测试(自我测试,修改代码,提交修改)
|
20
|
30
|
Reporting
|
报告
|
30
|
50
|
· Test Report
|
· 测试报告
|
20
|
30
|
· Size Measurement
|
· 计算工作量
|
20
|
20
|
· Postmortem & Process Improvement Plan
|
· 事后总结, 并提出过程改进计划
|
20
|
30
|
合计
|
|
1025
|
1460
|
六. 总结
刚看到这个题目的时候,我以为会很难,毕竟我对文件操作有了一些不好的印象,在理解过后,发现并不是很难。在写扩展功能的时候,因为对于题目要求没有理解正确,在写完功能后发现题目的要求并非如此,这给了我一个教训,以后需求分析要仔细。且自己对于函数的调用做得不是很好,在寻找目录下文件的函数中强行在进行一次指令判断,我觉得应该可以做的更好,但暂时没想出来。
源统计程序
原文:https://www.cnblogs.com/CloudDawnSun/p/12534782.html