• 源统计程序


    源统计程序(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("打开文件失败或文件不存在
    ");
        }
        else
        {
            c = fgetc(fp);
            while (c != EOF)
            {
                    charnum++;
                c = getc(fp);
                }
            printf("字符数:%d
    ", 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 == '
    ' || c == '
    ')
    18             linenum++;
    19         c = fgetc(fp);
    20     }
    21     printf("行数:%d
    ", 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
    ", 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 == '
    ')
            {
                if (jnull == 1) spaceline++;
                else codeline++;
                jnull = 1;                //每一行开始时默认为空行
            }
            if (c != ' ' && c != '
    ' && c != '
    '&&c!=-1)  //不是空格或换行或文件末尾,则不是空行
                jnull = 0;
        } while (!feof(fp));
        if (jnull == 1) spaceline++;    //最后一行判断(没有换行符要独立判断)
        else codeline++;
        printf("代码行:%d
    ", codeline);
        printf("空行:%d
    ", 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("文件路径错误或不存在
    ");
            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
    ", 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

     

    六. 总结

       刚看到这个题目的时候,我以为会很难,毕竟我对文件操作有了一些不好的印象,在理解过后,发现并不是很难。在写扩展功能的时候,因为对于题目要求没有理解正确,在写完功能后发现题目的要求并非如此,这给了我一个教训,以后需求分析要仔细。且自己对于函数的调用做得不是很好,在寻找目录下文件的函数中强行在进行一次指令判断,我觉得应该可以做的更好,但暂时没想出来。

  • 相关阅读:
    其实说起来要国庆节回去,心里有点担心再最后买不到票
    现在快要中秋节,之后又是国庆节
    天气开始降温,今天会下雨
    昨天晚上控制家里的电脑,与家里人视频
    有时候手机打开微信或者其它应用真的是非常慢
    手机有时候卡的不行,还是自己照顾着使用吧
    这几天晚上都是再看小别离,还是有点意思
    函数初识
    Python文件操作
    Python字符编码
  • 原文地址:https://www.cnblogs.com/CloudDawnSun/p/12534782.html
Copyright © 2020-2023  润新知