第三周作业(三)---WordCounter
需求是这样的。写出一个程序,模仿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的更多相关文章
- JAVA第三周作业(从键盘输入若干数求和)
JAVA第三周作业(从键盘输入若干数求和) 在新的一周,我学习了JAVA的IO编程.下面的代码实现了从键盘输入若干数求和的目标.import java.util.Scanner; public cla ...
- 第三周作业、实时操作系统µC/OS介绍及其它内容
作业要求 见<实时控制软件设计>第三周作业 1 阅读笔记--µC/OS 1.1 基本介绍 µC/OS是由Micrium公司研发的实时操作系统,以µC/OS-II或µC/OS-III为内核, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第三周作业
2018-2019-1 20189221<Linux内核原理与分析>第三周作业 实验二 完成一个简单的时间片轮转多道程序内核代码 实验过程 在实验楼中编译内核 编写mymain.c函数和m ...
- 2017-2018-2 1723《程序设计与数据结构》第三周作业 & 实验一 总结
作业地址 第三周作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1667 提交情况如图: 实验一:https://edu.c ...
- 第三周作业(一)VS安装及单元测试练习
第三周作业(一) 需求:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂,没 ...
- 2017-2018-1 JaWorld 第三周作业
2017-2018-1 JaWorld 第三周作业 团队展示 队员学号 队名 团队项目描述 队员风采 团队的特色 团队合照 团队初步合作 前两周的反思与总结 需要改进的地方 团队选题 *采访老师或有开 ...
- 2017-2018-1 JAVA实验站 第三周作业
2017-2018-1 JAVA实验站 第三周作业 团队展示 队名 JAVA实验站 拟作的团队项目描述 (2048)增加其他模式,使得2048更加丰富多彩 团队的首次合照 团队的特色描述 团队内部很团 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第三周作业
<Linux内核原理与分析>第三周作业 教材学习总结 第三章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,是正在执行的程序代码的实时结果:线程,是在进程中活动的对象.而Linu ...
- 第三周作业-课本&&视频学习
<网络攻防技术与实践>第三周作业 Part I 寻找自己留在互联网上的足迹并消除隐私 1.1 google/baidu搜索自己的qq号 搜索结果如图,搜到的有用信息其实就是图上这么几条,能 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第三周作业
<Linux内核原理与分析>第三周作业 一.上周问题总结: 第二周头脑风暴完成较慢 虚拟机libc配置错误 书本知识使用不够熟练 二.本周学习内容: 1.实验楼环境虚拟一个x86的CPU硬 ...
随机推荐
- JMeter乱码常见的解决方案
方法一.直接将JMeter中http请求中Content encoding改为utf-8 方法二.编辑JMeter安装目录:apache-jmeter-3.2\bin中的jmeter.properti ...
- Django【进阶篇】
目录 一.Model 二.admin 三.Form组件 四.Cookie 五.Session 六.分页 七.序列化 一.Model 数据库的配置 1.django默认支持sqlite,mysql, o ...
- 【PAT】B1036 跟奥巴马一起编程(15)(15 分
#include<stdio.h> int main() { int row,col; char c; scanf("%d %c",&col,&c); ...
- LNMP下动静分离部署phpmyadmin软件包
LNMP环境肯定是先要配置好的.可以参考我之前的博客.那我们直接进行配置,我这里使用了三台机器进行动静分离部署,第一台负责nginx反向代理,第二台负责php-fpm应用程序以及mariadb的服务器 ...
- shell脚本之数组
变量:存储单个元素的内存空间. 数组:存储多个元素的连续的内存空间. 数组名:整个数组只有一个名字: 数组索引:编号从0开始: 数组名[索引]: 引用数组中的某个元素:${ ARRAY_NAME [ ...
- JavaScript中数组的增删改查以及应用方式
数组的增加方法 1.push()方法向数组中末尾添加一个元素,原数组改变 var arr=[1,2,3,4]; var arr1=arr.push(6); console.log(arr);//打印出 ...
- HTTP数据组织方式
HTTP网络传输中的数据组织方式有三种方式: 1.HTML方式 2.XML方式 3.JSON方式 XML介绍:XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言) XM ...
- 2018-2019-2 网络对抗技术 20165318 Exp4 恶意代码分析
2018-2019-2 网络对抗技术 20165318 Exp4 恶意代码分析 原理与实践说明 实践目标 实践内容概述 基础问题回答 实践过程记录 1.使用schtasks指令监控系统 2.使用sys ...
- CSS三栏布局
一.绝对定位 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...
- ucml 子业务组件与行为参与者业务组件