• 简单实现wc.exe软件基本功能


    简单实现wc.exe软件基本功能

    软件需求分析:

    一、基本功能

    1. 支持 -c  统计字符数(char count)
    2. 支持 -w  统计单词数(word count)
    3. 支持 -l  统计总行数(line count)

    二、拓展功能

    1. 支持 -a 返回高级选项(代码行 空行 注释行)
    2. 支持 -s 递归处理符合条件的文件

    基础功能模块:

    一、实现字符数统计函数

    通过传参的方式将文件名以(char *filename)的方式传入函数,利用fgets()函数或fscanf()读取一行字符串,统计个数,逐行进行累加统计字符个数。通过wc.exe -c访问Charcount()函数。

    /*字符数统计函数*/
    int Charcount(char *filename)
    {
        int n=0;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            fscanf(fp,"%s",str);
            n=n+strlen(str);
        }
        fclose(fp);
        return n;
    }

    二、实现单词统计函数

    通过传参的方式将文件名以(char *filename)的方式传入函数,利用fscanf()读取字符串,当读取遇到空格时记为一个单词,并且以数字开头的不计为单词,也不统计汉字。并且以wc.exe -w方式访问Wordcount()函数。

    /*单词统计函数*/
    int Wordcount(char *filename)
    {
        int n=0;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            if(fscanf(fp,"%s",str)&&!(str[0] >='0'&&str[0] <='9'))
            {
                n++;
            }
        }
        fclose(fp);
        return n;
    }

    三、实现行数统计函数

    通过传参的方式将文件名以(char *filename)的方式传入函数,利用fgetc()读取单个字符,判断当前读取字符是否为换行符,如果是换行符将行数加一。并且以wc.exe -l方式访问Linecount()函数。

    /*行数统计*/
    int Linecount(char *filename)
    {
        int n=0;char ch;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            ch=fgetc(fp);
            if(ch=='
    ')
            {
                n++;
            }
        }
        fclose(fp);
        return n;
    }

    高级功能模块:

    通过传参的方式将文件名以(char *filename)的方式传入函数,这里对于空行、注释行、代码行,我们分别用不同的函数来实现功能,最后用户通过wc.exe  -s-a命令来对这三个函数进行访问。统计空行函数specialcount();统计注释行函数signalcount();统计代码行函数keycount()。

    /*统计注释行函数*/
    void signalcount(char *filename)
    {
        int len=0,i=0;signline=0;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            fgets(str,sizeof(str),fp);
            len=strlen(str);
            for(i=0;i<len;i++)
            {
                if((str[i]=='/'&&str[i+1]=='/')||(str[i]=='/'&&str[i+1]=='*'))
                {
                    signline++;
                    break;
                }
            }
        }
        fclose(fp);
        cout<<"注释行数: SignLine="<<signline<<endl<<endl;
    }
    
    /*统计空行函数*/
    void specialcount(char *filename)
    {
        int len=0,i=0,flag=0;
        emptyline=0;keyline=0;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            flag=0;
            fgets(str,sizeof(str),fp);
            len=strlen(str);
            for(i=0;i<len;i++)
            {
                if((str[i]=='/'&&str[i+1]=='/')||(str[i]=='/'&&str[i+1]=='*'))
                {
                    flag=1;
                    break;
                }
            }
            if((str[0] =='
    '||str[0]=='}'||str[0]=='{')&&(flag==0))
            {
                emptyline++;
            }
        }
        fclose(fp);
        cout<<"空行行数: EmptyLine="<<emptyline<<endl<<endl;
    }
    
    /*统计代码行函数*/
    void keycount(char *filename)
    {
        int len=0,i=0;keyline=keyline-emptyline;
        fp=fopen(filename,"r");
        if(fp==NULL)
        {
            cout<<"
    请在文件中添加内容"<<endl;
            exit(-1);
        }
        while(!feof(fp))
        {
            fgets(str,sizeof(str),fp);
            len=strlen(str);
            if(len>1)
            {
                for(i=0;i<len;i++)
                {
                    if((str[i]!='/'&&str[i+1]!='/')||(str[i]!='/'&&str[i+1]!='*'))
                    {
                        keyline++;
                    }
                    break;
                }
            }
        }
        fclose(fp);
        cout<<"
    代码行数: KeyLine="<<keyline<<endl<<endl;
    }

    主函数模块:

    在main()函数中我们主要实现用户交互功能以及文件建立等操作。

    int main()
    {
        while(1)
        {
            char ch[20];
            cout<<"输入用户命令:wc.exe ";
            scanf("%s",ch);
            if(ch[1]=='c')
            {
                cout<<"
    请输入文件位置:";
                cin>>Filename;
                charcount=Charcount(Filename);
                cout<<"
    字符个数: CharCount="<<charcount<<endl<<endl;
            }
            if(ch[1]=='w')
            {
                cout<<"
    请输入文件位置:";
                cin>>Filename;
                wordcount=Wordcount(Filename);
                cout<<"
    单词个数: WordCount="<<wordcount<<endl<<endl;
            }
            if(ch[1]=='l')
            {
                cout<<"
    请输入文件位置:";
                cin>>Filename;
                linecount=Linecount(Filename)+1;
                cout<<"
    文件行数: LineCount="<<linecount<<endl<<endl;
            }
            if(ch[1]=='s'&&ch[3]=='a')
            {
                cout<<"
    请输入文件位置:";
                cin>>Filename;
                keycount(Filename);     //代码行
                signalcount(Filename);  //注释行
                specialcount(Filename); //空行
            }
        }
        return 0;
    }

    总体功能测试:

    对于其他类型文件进行测试。

    总结:

    这次是实现一个简单的字符单词统计软件,主要是对文件的操作;熟悉对于文件的各种读写操作,本次作业我基本上实现了要求的所有功能。至此本次的作业就完成了,当然也有很多的不完善的地方,在以后的实践中我会不断改进的。

  • 相关阅读:
    my.cnf 配置文档
    win11 默认 右击 老菜单
    慎重修改 profile 文件
    响应延迟数据集 p90/p99 是什么
    Windows 修改 注册表 鼠标右键 菜单 使用**打开
    windows 系统 开启 mysql binlog 变更数据后 根据日志 寻找变更前的数据
    Mysql 的 read_only 只读属性 权限分配 动态权限
    utf8 和 utf8mb4 的区别
    MySQL 数据库 隔离 的 四个级别 和 事务 的 四个特性
    26. 删除有序数组中的重复项
  • 原文地址:https://www.cnblogs.com/199489KPY/p/5312554.html
Copyright © 2020-2023  润新知