需求是这样的。写出一个程序,模仿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. 解决windows下git push卡住问题的方法

    问题描述: 在windows下向使用git协议传输的Git Repo进行push时会卡住. -- 这是windows上的msysgit的bug,在新版本上已经修复,但要在.gitconfig中做一项配 ...

  2. 百度-淘宝-360搜索引擎搜索API

    百度(baidu) Api地址:http://suggestion.baidu.com/su?wd=设计&p=3&cb=window.bdsug.sug window.bdsug.su ...

  3. vsftpd不支持目录软链接的解决办法

    vsftpd本身不支持软连接,而在用FTP共享的时候又不想移动文件位置,便在网上找到了一个workaround: Linux内核从2..0开始支持把一部分文件系统挂载到文件系统中的其他位置,mount ...

  4. SSRS奇怪报错Could not update a list of fields for the quer.

    今天遇到一个奇怪的问题,SSRS我觉得是个半成品,很多东西都搞不了.写了一段SQL,本来SQL写法都有点怪了,如下 WITH TMP_A AS (SELECT *,ROW_NUMBER() OVER( ...

  5. leetcode 44. Wildcard Matching(模糊匹配)

    搬运工了- - https://blog.csdn.net/jmspan/article/details/51460021

  6. svn 更新

    dev更新流程: 1.打开软件,文件—>打开,弹出右边对话框链接dev地址      2.在窗口输入cd /var/www/user 回车 3.输入svn up 则更新dev代码完成 本地提交到 ...

  7. dns与wins的区别

    将主机名字解析称为ip地址有四种办法: dns.winds.hosts文件.lmhosts文件 dns和hosts是很多系统cout采用的一个名称解析的方法,wins和lmhosts是微软的操作系统此 ...

  8. Excel中concatenate函数的使用方法

    你还在为Excel中concatenate函数的使用方法而苦恼吗,今天小编教你Excel中concatenate函数的使用方法,让你告别Excel中concatenate函数的使用方法的烦恼. 经验主 ...

  9. Python 扩展插件

    扩展插件 我下载的本版自带 pip下载工具 cmd-pip 下载插件 pip install HTMLParser 如果提示版本问题,更新PIP 别用开始里面的CMD 使用管理者权限 请注意差别 输入 ...

  10. 剑指offer从上往下打印二叉树 、leetcode102. Binary Tree Level Order Traversal(即剑指把二叉树打印成多行、层序打印)、107. Binary Tree Level Order Traversal II 、103. Binary Tree Zigzag Level Order Traversal(剑指之字型打印)

    从上往下打印二叉树这个是不分行的,用一个队列就可以实现 class Solution { public: vector<int> PrintFromTopToBottom(TreeNode ...