自己刚学习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
不足之处,请多指教;