c语言,代码统计器[线程版]、盗墓者是个丑奴儿

2024-01-12 03:59

本文主要是介绍c语言,代码统计器[线程版]、盗墓者是个丑奴儿,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

//盗墓者是个丑奴儿,原

//博主个人网站 :https://daomu.kaige123.com

//打完一波小广告,进入正题

 

//头文件引入

#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
#include <dirent.h>
 

//函数声明

int opend(const char * pathname);
int judge(char * pathname);
char * str(const char * str1,const char * str2);
void readf(const char * pathname);

DIR * dir=NULL;
int in=0;                       //打开参数目录,记录的目录个数
char * arr[100]={0};     //打开输出参数,对目录路径收集

 

//参数:pathname,作用:opendir打开pathname。判断:如果是文件,调用judge()统计代码。如果是目录,调用存储进入arr数组

int opend(const char * pathname){
        dir=opendir(pathname);
        if(dir==NULL)
        return -1;
        struct dirent * reado=NULL;
        while((reado=readdir(dir))!=NULL){
                char * tmps=NULL;
                if(reado->d_name[0]=='.')
                continue;
                tmps=str(pathname,reado->d_name);
                if(reado->d_type==DT_DIR){
                        arr[in++]=tmps;
                //      readf(tmps);
                }else{
                        judge(tmps);
                }
                if(reado==NULL)
                free(tmps);
        }
}
 

int y=0;
pthread_mutex_t s;      //互斥锁

void * run(void * arg){                        //给创建线程,所绑定的方法
        pthread_mutex_lock(&s);          //加锁
        readf(arr[y++]);
        pthread_mutex_unlock(&s);      //解锁,因为下面用了join阻塞回收子线程,这里也可有可无
}

 

//参数:pathname,作用,递归目录,如果发现递归到文件了,调用judge()统计代码。如果是目录,自调

void readf(const char * pathname){
        DIR * dir=opendir(pathname);
        struct dirent * reado=NULL;
        while((reado=readdir(dir))!=NULL){
                char * tmps=NULL;
                if(reado->d_name[0]=='.')
                continue;
                tmps=str(pathname,reado->d_name);
                if(reado->d_type==DT_DIR){
                        readf(tmps);
                }else{
                        judge(tmps);
                }
                if(reado==NULL)
                free(tmps);
        }
}
 

//count_num统计字数

//rows统计行数

//统计的.c文件个数

int count_num=0;
int rows=0;
int gs=0;

 

//参数:pathname(文件路径),作用,过滤出.c文件,统计.c文件的字数,行数

//第一步,先等于"\0",去掉\。第二步,strstr过滤出.c文件。第三步,打开处理后的pathname。第四步,获得文件大小,read读取内容。第五步:过滤掉内容于10与32的,10空格,32换行。

//过滤10与32的剩余长度,就是统计出:文件有效长度。过滤掉32,就是统计出:文件的有效行数

int judge(char * pathname){
        pathname[strlen(pathname)-1]='\0';

        if(strstr(pathname,".c")==NULL)
        return 0;
        gs++;

        int fd=open(pathname,O_RDWR);
        int length=lseek(fd,0,SEEK_END);
        close(fd);

        fd=open(pathname,O_RDWR);

        char ar[length];
        memset(ar,'0',length);
        ar[sizeof(ar)]='\0';
        read(fd,ar,length);

        for(int i=0;i<length;i++){
                if(ar[i]!=10 && ar[i]!=32)
                count_num++;
                if(ar[i]==10)
                rows++;
        }
        close(fd);
}

 

//参数:str1,str2。将str1yustr2拼接,加/。如/usr与a.out,返回/usr/a.out/

char * str(const char * str1,const char * str2){
        int size1=strlen(str1);
        int size2=strlen(str2);
        char * arr=(char *)malloc(size1+size2+2);
        memset(arr,'0',size1+size2);
        memcpy(arr,str1,size1);
        memcpy(&(arr[size1]),str2,strlen(str2));
        arr[size1+size2]='/';
        return arr;
}
 

//main接收传参,进行程序运行

int main(int arg,char ** arv){

        if(arv[1]!=NULL)
        opend(arv[1]);

        for(int i=0;i<in;i++){
                pthread_t s;
                pthread_create(&s,NULL,run,NULL);
                pthread_join(s,NULL);
        }

        pthread_mutex_destroy(&s);         //回收互斥锁

        printf("number=%d rows=%d gs=%d\n",count_num,rows,gs);

        return 0;
}

 

运行结果:上面是带线程的运行,下面是不带线程的运行

这篇关于c语言,代码统计器[线程版]、盗墓者是个丑奴儿的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/596731

相关文章

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)