Chinaunix首页 | 论坛 | 博客
  • 博客访问: 555068
  • 博文数量: 92
  • 博客积分: 2511
  • 博客等级: 少校
  • 技术积分: 932
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-19 10:10
文章分类
文章存档

2011年(6)

2010年(27)

2009年(37)

2008年(22)

我的朋友

分类: LINUX

2010-03-04 23:25:00

   我曾经在博客里写过一篇如何遍历linux文件夹下的文件的文章,那时候用的是ntfw等函数(遍历Linux文件夹),今天我在学习shell的时候想实现shell的tree指令,一开始写出来的效果不好,于是我打算用还比较熟悉的c语言先写个C版本的出来,没想到折腾了不少时间。。。特此写出来,另外附上一些过程。
在我的Linux机器上当前所在的文件夹位置使用tree得到的是如下的结构(可以检验我们的程序是否正确,注意.开头的文件在这里没有显示,可以用tree -a pathname来显示隐藏文件)

一开始的时候是一个小错误,就是strcmp是以返回0来指示两个字符串是一样的,在这里竟然忘记浪费了点时间。后来的一些小错误不提了,关键的一个错误是,我发现最上层的两层目录可以递归出来,到了我那个desktop和workspace文件夹的时候却没有了。觉得很奇怪,因为我用终端连接的主机,没有IDE可以使用,gdb又不习惯,费了很大的劲才发现desktop这些目录在stat之前是得到的,之后却消失了。。。于是怀疑是stat出错了,一看返回值,果然,于是加入了下面代码里的一系列的case语句,终于得到了errno的值,原来是ENOENT,我man了stat函数之后直到,这个错误是指A component of the path path does not exist, or the path is an empty string. 原来如此!原来提供给stat的路径是不完整的,我加入了以下五行
终于解决了!
这样基本上是实现了tree了----当然效率是不能相比的,还有就是格式呵呵,以下贴上我的代码:

1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 #include <dirent.h>
  5 #include <sys/stat.h>
  6 #include <string.h>
  7 #include <stdlib.h>
  8 #include <errno.h>
  9
 10 void print_tree(char *filename,int blank);
 11
 12 int main(int argc, char *argv[])
 13 {
 14 printf("/home/p/p/SigKill\n");
 15 print_tree("/home/p/p/SigKill",2);
 16 return 0;
 17 }
 18
 19 void print_tree(char *filename,int blank){
 20
 21 DIR *dir = opendir(filename);
 22 if(dir == NULL)
 23 perror("opendir");
 24
 25 struct dirent *ent;
 26 int i=0;
 27
 28 while((ent=readdir(dir)) != NULL){
 29
 30 if(!strcmp(ent->d_name,".") ||\
 31 !strncmp(ent->d_name,"..",2))
 32     continue;
 33
 34 struct stat st;
 35
 36 char *name = (char *)malloc(sizeof(char)*1024);
 37 memset(name,'\0',sizeof(char)*1024);
 38 strcpy(name,filename);
 39 strcat(name,"/");
 40 strcat(name,ent->d_name);
 41
 42 int f=stat(name,&st);
43 if(f == -1){
 44 switch(errno){
 45 case EACCES:puts("EACCES");break;
 46 case EBADF:puts("EBADF");break;
 47 case EFAULT:puts("EFAULT");break;
 48 case ENOENT:puts("ENOENT");break;
 49 case ENOMEM:puts("ENOMEM");break;
 50 case ENOTDIR:puts("ENOTDIR");break;
 51 }
 52
 53 }
 54
 55 if(S_ISDIR(st.st_mode)){
 56 for(i=0;i<blank;i++)
 57 printf(" ");
 58 char *name = (char *)malloc(sizeof(char)*1024);
 59 memset(name,'\0',sizeof(char)*1024);
 60 strcpy(name,filename);
 61 strcat(name,"/");
 62 strcat(name,ent->d_name);
 63 printf("%s\n",ent->d_name);
 64 print_tree(name,blank+2);
 65 free(name);
 66 }
 67 else{
 68 for(i=0;i<blank;i++)
 69 printf(" ");
 70 printf("%s\n",ent->d_name);
 71 }
 72 }
 73
 74 }
 75

话说还是vi语法高亮好看啊~~
阅读(6205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~