需求是这样的。写出一个程序,模仿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. Java jni字符串转换

    1.jstring转QString 对于Qt5.2以上(含)可以用QAndroidJniObject::toString(),详见这里:https://stackoverflow.com/questi ...

  2. 【PAT】B1076 Wifi密码(15 分)

    注意接收字符时缓冲区的换行要接受掉 #include<stdio.h> int main() { int n; scanf("%d", &n); n *= 4; ...

  3. shell脚本之数组

    变量:存储单个元素的内存空间. 数组:存储多个元素的连续的内存空间. 数组名:整个数组只有一个名字: 数组索引:编号从0开始: 数组名[索引]: 引用数组中的某个元素:${ ARRAY_NAME [ ...

  4. Python getting started guide

    Get up in the morning. The first thing is to write a blog, although it uses machine translation, it ...

  5. Git的上传步骤

    Git的上传步骤 1.Git的命令基础 Git是当下最流行的版本控制工具(VCS),由linux系统之父linus开发.它能实现 团队中的代码协作开发,它在代码同步和代码管理方面功能强大,理念先进. ...

  6. Nginx使用教程(一):下载并编译安装Nginx

    安装依赖 <br\>我们已经选择下载程序源代码进行手动编译,而不是使用软件包管理器(如Yum,Aptitude或Yast)进行安装. 这个选择有两个原因. 首先,软件包可能不包含在您的Li ...

  7. centos7下安装docker(3.2创建镜像build)

    通过Dockerfile创建镜像 注:这个Dockerfile一开始真的不知道是在哪来的,还以为是在官网下载下来得(当然网上也有很多dockerfile的模板,参考:https://hub.docke ...

  8. Maven Dependency Scope

     官方API描述 Dependency scope 是用来限制Dependency的作用范围的, 影响maven项目在各个生命周期时导入的package的状态. 自从2.0.9后,新增了1种,现在有了 ...

  9. BZOJ3295:[CQOI2011]动态逆序对(CDQ分治)

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  10. document.documentElement.scrollTop(获取滚动条位置)

    要获取当前页面的滚动条纵坐标位置,用:document.documentElement.scrollTop;而不是:document.body.scrollTop;documentElement 对应 ...