Linux下代码行查询,显示文件树,搜索文件

自己刚学习Linux时,写的一个小工具;
1,查询写了多少行C/C++代码;
2,搜索文件的绝对路径;
3,显示文件树。

/***************************
 *
 *链栈stack.c
 * ************************/
//元素节点
typedef struct Node
{
    char *str;
    struct Node *next;
    struct Node *fron;
}Node;
//栈的头节点
typedef struct Snode
{
    Node *next;
    Node *end;
}Snode,*stack;
//创建一个节点
Node *Buynode(char *val)
{
    int len = strlen(val);
    Node *p = (Node*)malloc(sizeof(Node));
    assert(p != NULL);
    p->next = NULL;
    p->fron=NULL;
    p->str = (char*)malloc(sizeof(char)*(len+1));
    strcpy(p->str, val);
    return p;
}
//初始化一个栈
void Init(stack a)
{
    a->next = NULL;
    a->end = NULL;
}
//入栈
void push(stack a, char *val)
{
    Node*p = Buynode(val);
    if(a->next == NULL)
    {   
        a->next = p;
        a->end = p;
    }   
    else
    {   
        a->end->next = p;
        a->end = p;
    }   
}
//查找倒数第二个节点
Node*search(stack a)
{
    if(a->next==NULL || a->next->next==NULL)
    {   
        return NULL;
    }   
    else
    {   
        Node*p=a->next;
        for(;p->next->next != NULL; p=p->next)
        {   
            ;   
        }   
        return p;
    }   
}
//出栈
void pop(stack a)
{   
    if(a->next == NULL)
    {   
        printf("栈已空\n");
        a->end = NULL;
        return ;
    }   
    if(a->next->next==NULL)
    {   
        free(a->end);
        a->next->next=NULL;
        a->end = NULL;
        return;
    }   
    Node*p = a->end;
    Node*q = a->next;
    for(;q->next->next != NULL; q=q->next)
    {   
        ;   
    }   
    q->next = NULL;
    free(p);
    a->end = q;
    /*  
    if(a->next == NULL)
    {
        printf("栈已空!\n");
        return;
    }
    Node *p = a->end;
    a->end = search(a);
    free(p);
    */
}
void Destroystack(stack a)
{
    Node*p;
    while( a->next != NULL )
    {   
        p = a->next;
        a->next=a->next->next;
        free(p);
    }   
    a->end = NULL;
    a->next = NULL;
}
//显示一个栈
void show(stack a)
{
    Node*p = a->next;
    for(; p != NULL; p=p->next)
    {   
        printf("%s/",p->str);
    }   
}
Snode b;
stack a=&b;
//遍历文件夹,查找同名文件
void Searchpath( char *dir,  char *buff)
{
    push(a,dir);
    DIR *dp;
    struct stat statbuff;
    struct dirent *entry;
    if( (dp=opendir(dir))==NULL )
    {   
        pop(a);//必不可少
        return ;
    }   
    chdir(dir);
    while( (entry = readdir(dp)) != NULL )
    {   
        lstat(entry->d_name, &statbuff);
        if(S_ISDIR(statbuff.st_mode))
        {   
            if((strcmp(".",entry->d_name))==0  ||  
                strcmp("..",entry->d_name)==0 )
            {   
                continue;
            }   
            if(strcmp(entry->d_name, buff)==0)
            {   
                show(a);
                printf("%s\n",buff);
            }   
        //  printf("%s\n",entry->d_name);
            Searchpath(entry->d_name, buff);
        }   
        else
        {   
            if(strcmp(entry->d_name, buff)==0)
            {   
                show(a);
                printf("%s\n",entry->d_name);
            }   
        //  printf("%s\n",entry->d_name);
        }   
    }   
    pop(a);
    chdir("..");
    closedir(dp);   
}

/***************************
*codeline query tool
*version 3.0  done
*
***************************/


#include<unistd.h>
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<time.h>
#include"stack.c"
static int codecount=0;
static int i=0;
static int codecount2=0;
//以最后2或3或4位来判断文件是否是要查找的.c .h .cpp文件
int mystrcmp(char*str)
{
    int len=strlen(str);
    if(len<3)
    {   
        return -1; 
    }   
    if((*(str+len-1)=='h') && (*(str+len-2)=='.'))
    {   
        return 0;
    }    
    else if((*(str+len-1)=='c') && (*(str+len-2)=='.'))
        {   
                return 0;
        }   
/* 此段代码为测试C#用;
  else if((*(str+len-1)=='s') &&  
         (*(str+len-2)=='c')&&
        (*(str+len-3)=='.'))
        {
                return 0;
        }
*/    
    else if((len>6) && (*(str+len-1)=='p')
             && (*(str+len-2)=='p')
            && (*(str+len-3)=='c')
             && (*(str+len-4)=='.'))

        {   
                return 0;
        }   
return -1; 
}
//遍历文件夹,输出目录树
void myprintdir(char *dir, int depth)
{
    int in; 
    char c;
    DIR *dp;
    char *buff;
    struct dirent *entry;
    struct stat statbuff;
    if((dp = opendir(dir) )== NULL)
    {   
        printf("cannot open directory:%s\n",dir);
        return;
    }   

    chdir(dir);
    while((entry = readdir(dp)) != NULL)
    {   
        lstat(entry->d_name, &statbuff);
        if(S_ISDIR(statbuff.st_mode))//判断是否为目录
        {   
            if(strcmp(".",entry->d_name)==0 || //排除掉.和..
            strcmp("..",entry->d_name)==0  )
            {   
                continue;
            }   
            printf("%*s%s/\n",depth," ", entry->d_name);
            myprintdir(entry->d_name,depth+6);
        }   
        else 
        {   
            printf("%*s%s\n",depth," ",entry->d_name);
        }   
    }   
    chdir("..");
    closedir(dp);
}



//显示出每个c/c++代码的详细信息
//文件的大小,文件的权限,文件的修改日期
void Mydetaildir(char *dir)
{
    int codeline=0;
    int i=0;
    int readnu;
    char buff[1024];
    memset(buff,0,1024);
    int in; 
    DIR *dp;
    struct stat statbuff;
    struct dirent *entry;
    if( (dp=opendir(dir))==NULL )
    {   
        printf("%s cannot open !\n",dir);
        return;
    }   
    chdir(dir);//进入目录类似shell里的cd
    while( (entry=readdir(dp)) != NULL )
    {   
        lstat(entry->d_name, &statbuff);
        if(S_ISDIR(statbuff.st_mode))
        {   
            if(strcmp(".",entry->d_name)==0 ||  
               strcmp("..",entry->d_name)==0)
            {   
                continue;
            }   
            Mydetaildir(entry->d_name);
        }   


        if(S_ISREG(statbuff.st_mode))//判断是否为文件
        {   
            if(mystrcmp(entry->d_name)==0)
            {   
                in=open(entry->d_name,O_RDONLY);
                if(in == -1) 
                {   
                    printf("%s open error!",entry->d_name);
                }   
                while( (readnu= read(in,buff,1024)) )//读到buff里;
                {   
                    for(i=0; i<readnu; ++i)
                    {   
                        if( buff[i]=='\n')
                        {   
                            codeline++;    
                        }   
                    }   
                }   
                printf("%-s---codeline: %d\n",entry->d_name,codeline);
                codecount2+=codeline;
                codeline = 0;
                close(in);
            }   
        }   
    }   
    chdir("..");
    closedir(dp);
}


//遍历文件夹,统计总的代码行;
void myreaddir(char *dir)
{
    int i=0;
    int in; 
    int readnu = 0;
    char buff[1024];
    memset(buff, 0 , 1024);
    DIR *dp;
    struct dirent *entry;
    struct stat statbuff;
    if((dp = opendir(dir) )== NULL)
    {   
        printf("%s:open error\n",dir);
        return;
    }   

    chdir(dir);//进入指定目录
    while((entry = readdir(dp))!= NULL)
    {   
        lstat(entry->d_name,&statbuff);//通过文件名获取文件信息
        if(S_ISDIR(statbuff.st_mode))
        {   
            if(strcmp(entry->d_name,".")==0 ||
                       strcmp(entry->d_name,"..")==0)
                    {   
                            continue;
                     }   

        //  printf("%s/\n",entry->d_name);
             myreaddir(entry->d_name);
        }   
        if(S_ISREG(statbuff.st_mode))
        {   
            if(mystrcmp(entry->d_name)==0)
            {
            //   printf("file name==%s  ",entry->d_name);

                in=open(entry->d_name ,O_RDONLY);
                if(in == -1)
                {
                    printf("%s open error!\n",entry->d_name);
                    return ;
                }
                while(readnu=read(in, buff , 1024) )
                {
                    for(i=0; i<readnu; ++i)//i一定要小于readnu,而不是1024;
                    {
                        if(buff[i]=='\n')
                        {
                            codecount++;
                        }
                    }
                }
                close(in);
            }
        }

    }
    chdir("..");
    closedir(dp);
}

//主菜单
void menu()
{
    int flg = 1;
    int choice = 9;
    while(flg)
    {
        printf("\n");
        printf("\033[;31m ------------------------------\n");
        printf("| 1----查询我的C/C++代码行     |\n");  //done
        printf("| 2----查询每个.h .c .cpp的行数|\n");//done
        printf("| 3----查询文件树              |\n");//done
        printf("| 4----查询文件的绝对路径      |\n");
        printf("| 0----退出                    |\n");
        printf(" ----------------------------\033[0m ");
        printf("\n\n\n");
        printf("请输入您的选择:");
        scanf("%d",&choice);
        switch(choice)
        {
            case 0://退出
                {
                    printf("\033[;32m感谢您的使用!!bye bye!!\033[0m\n");
                    printf("\n");
                    exit(0);
                    break;
                }
            case 1://查询C C++代码行;
                {
                    char mydir[100];
                    printf("请输入您的文件夹路径:");
                    scanf("%s",mydir);
                    myreaddir(mydir);
                    printf("\033[;31m 代码总行数:%d\033[0m",codecount);
                    codecount = 0;
                    break;
                }
            case 3://查询文件树;
                {
                    char mydir[100];
                    printf("请输入您的文件夹路径:");
                    scanf("%s",mydir);
                    myprintdir(mydir,0);
                    break;
                }

            case 2://查询每个.c.h.cpp文件的详细信息;
                {
                    char mydir[100];
                    printf("请输入您的文件夹路径:");
                    scanf("%s",mydir);
                    Mydetaildir(mydir);
                    printf("\033[;32m此文件夹下共有代码:%d  行\033[0m\n",
                                       codecount2);
                    break;
                }
            case 4://查询文件的绝对路径
                {
                    Node*p;
                    char buff[20];
                    printf("请输入您要查询的文件夹名:");
                    scanf("%s",buff);
                    Searchpath("/",buff);
                    a->next=NULL;
                    a->end=NULL;
                    show(a);

                    break;
                }
            default:
                {
                    printf("\033[;31m输入有误! 请重新输入!!\033[0m");
                    menu();
                    break;
                }
        }
    }
}


int main()
{
    Init(a);
    printf("\n\n");
    printf("\033[;32m欢迎进入Codeline Query Tool !\033[0m\n");
    menu();
    exit(0);
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             //Bot

不足之处,请多指教;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值