C语言实现shell命令wc,用于统计目录文件内容

/* ************************************************************************
> File Name:     wc.c
> Author:        Wheiu
> email:    1595386336@qq.com
> Created Time:  Thu 23 Dec 2021 02:28:55 PM +08
> Description:实现shell命令wc,用于统计目录文件内容
>             1、一共有多少个C文件
>             2、一共有多少个H文件
>             3、一共有多少个汇编文件`在这里插入代码片`
>             4、一共有多少个单词、行
>             5、整个项目有多少行代码
 ************************************************************************/
#include<stdio.h>
#include<dirent.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>


int do_wc(char Filename[]);//读取每个文件中有多少行 多少单词
int foreach_dir(char dirname[]);//遍历每个子目录

int main(int argc, char *argv[])
{
    foreach_dir(argv[1]);
    return 0;

}

int foreach_dir(char dirname[])
{
    DIR *dir_ptr;//目录指针
    struct dirent * entry_prt;
    dir_ptr = opendir(dirname);//打开通过命令行参数传进来的目录
    if(dir_ptr == NULL)
    {
        perror("opendir error\n");
        return -1;
    }
    char full_path_name[128];
    struct stat buf;//使用stat结构体读取文件属性 保存到buf中
    while((entry_prt = readdir(dir_ptr)) != NULL) //循环读取目录
    {
        if((strcmp(entry_prt -> d_name, ".") && strcmp(entry_prt -> d_name, "..")) == 0)
            continue;
        strcpy(full_path_name, dirname);
        if(full_path_name[strlen(full_path_name) - 1] != '/')
            strcat(full_path_name, "/");
        strcat(full_path_name, entry_prt -> d_name);
        
       if(stat(full_path_name, &buf) < 0)//返回关于文件的信息 
       {
           perror("stat error\n");
           return -1;
       }
       if(S_ISDIR(buf.st_mode))//如果是一个子目录,循环读取目录
           foreach_dir(full_path_name);
       else
       {
           if(strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".c") && //过滤C文件
              strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".h") && //过滤C文件
              strcmp(entry_prt -> d_name + strlen(entry_prt -> d_name) - 2, ".s"))//过滤C文件
               continue;
           else
               //do_wc函数参数是绝对路径,而entry_prt->d_name是字符串,需要转换
               do_wc(full_path_name);//读取目录下的文件名并传入do_wc函数
       }
    }
    closedir(dir_ptr);
    return 0;
}


int do_wc(char Filename[])
{
    FILE *fp;
    static unsigned int lines = 0;//统计行数
    static unsigned int words = 0;//统计单词数
    static unsigned int files = 0;//统计文件数

    int word_flag = 0;//用于表示一个单词统计完成 标记位
    char ch;
    fp = fopen(Filename, "r");
    if(fp == NULL)
    {
        perror("fopen");
        return -1;
    }
    while((ch = fgetc(fp)) != EOF)
    {
        if(ch == '\n')//统计行数
            lines++;
        if(ch == '\n' || ch == ' ' || ch == '\t')//统计单词
        {
            word_flag = 1;
            continue;
        }
        else
        {
            if(word_flag == 1)
            {
                words++;
                word_flag = 0;
            }
        }
    }
    fclose(fp);
    printf("%s\n", Filename);
    printf("files: %d\n", files++);
    printf("lines: %d\n", lines);
    printf("words: %d\n", words);
    return 0;
} 

运行结果如图:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值