LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 989|回复: 2

[求助]用c实现ls -l(已解决)

[复制链接]
发表于 2006-11-6 01:13:30 | 显示全部楼层 |阅读模式
我是用opendir()打开,然后用readdir()读目录,之后用stat()获得文件信息,但问题 是只有在读当前目录时正常,非当前目录就会出现找不到文件的错误,我是新手,不知有没人愿意帮助看一下,万分感激,我想问题应该是stat()在所获得路径有问题,但不知该怎么办.


  1. #include<stdio.h>
  2. #include<dirent.h>
  3. #include<sys/stat.h>
  4. #include<sys/types.h>
  5. #include<pwd.h>
  6. #include<grp.h>
  7. #include<string.h>

  8. DIR            *dp;
  9. struct dirent  *dirp;
  10. struct stat    statbuf;
  11. void showfileinfo(char *filename, struct stat *buf);
  12. void dostat(char *filename);
  13. char *uid_to_name(uid_t);
  14. char *gid_to_name(gid_t);
  15. void do_ls(char[]);

  16. int main(int argc, char *argv[])
  17. {
  18.   if (argc == 1)
  19.       do_ls(".");
  20.   else
  21.         do_ls(argv[1]);
  22. }

  23. void do_ls(char dir[]) {
  24.   if ((dp=opendir(dir))==NULL) {
  25.     printf("can't open %s\n", dir);
  26.     exit(1);
  27.     }
  28.     while ((dirp=readdir(dp))!=NULL)  
  29.       dostat(dirp->d_name);
  30.    closedir(dp);
  31.   exit(0);
  32. }

  33. void dostat(char *filename) {
  34.         struct stat info;
  35.         if (stat(filename,&info)==-1) {
  36.           printf("stat file error!\n");
  37.           exit(1);
  38.               }
  39.         else
  40.           showfileinfo(filename,&info);
  41. }

  42. void showfileinfo(char *filename, struct stat *buf) {
  43.   /*display the file info */

  44.   char *uid_to_name(uid_t);
  45.   char *ctime(time_t *);
  46.   char *gid_to_name(gid_t);

  47.   int mode=buf->st_mode;
  48.   char str[11];

  49.   strcpy(str, "----------");

  50.   if(S_ISDIR(mode)) str[0] = 'd';
  51.   if(S_ISLNK(mode)) str[0] = 'l';

  52.   if(mode & S_IRUSR) str[1] = 'r';
  53.   if(mode & S_IWUSR) str[2] = 'w';
  54.   if(mode & S_IXUSR) str[3] = 'x';

  55.   if(mode & S_IRGRP) str[4] = 'r';
  56.   if(mode & S_IWGRP) str[5] = 'w';
  57.   if(mode & S_IXGRP) str[6] = 'x';

  58.   if(mode & S_IROTH) str[7] = 'r';
  59.   if(mode & S_IWOTH) str[8] = 'w';
  60.   if(mode & S_IXOTH) str[9] = 'x';

  61.    printf("%s ", str);
  62.    printf("%4d ", buf->st_nlink);
  63.    printf("%-8s ", uid_to_name(buf->st_uid));
  64.    printf("%-8s ", gid_to_name(buf->st_gid));
  65.    printf("%8ld ", (long)buf->st_size);
  66.    printf("%.12s ", 4+ctime(&buf->st_mtime));
  67.    printf("%s\n", filename);
  68. }

  69. char *uid_to_name(uid_t uid)
  70. /*
  71. * returns pointer to username associated with uid, uses getpw()
  72. */
  73. {
  74.   struct passwd  *pw_ptr;
  75.   static char numstr[10];

  76.   if( (pw_ptr = getpwuid(uid)) == NULL)
  77.   {
  78.     printf(numstr, "%d", uid);
  79.     return numstr;
  80.   }
  81.   else
  82.     return pw_ptr->pw_name;
  83. }

  84. char *gid_to_name(gid_t gid)
  85.      /*
  86.       *returns pointer to groupname associated with gid, uses getgr()
  87.       */
  88. {
  89.   struct group *grp_ptr;
  90.   static char numstr[10];

  91.   if ((grp_ptr = getgrgid(gid)) == NULL)
  92.   {
  93.     sprintf(numstr, "%d", gid);
  94.     return numstr;
  95.   }
  96.   else
  97.     return grp_ptr->gr_name;
  98. }
复制代码
发表于 2006-11-6 17:41:44 | 显示全部楼层
楼主的问题是传递给 dostat() 的 filename 是相对 do_ls() 中的 dir 的,因此有两种解决方法,第一种就是切换你的程序的路径;
  1. if (argc != 1) chdir(argv[1]);
  2. do_ls(".");
复制代码
或者就是把 do_ls() 中传递给 dosta() 的参数改一下
  1.         while ((dirp=readdir(dp))!=NULL) {
  2.                 char s[1024];
  3.                 strcpy(s, dir);
  4.                 strcat(s, dirp->d_name); /* here we assume dir is ended with '/' */
  5.                 dostat(s);
  6.         }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-11-6 17:57:48 | 显示全部楼层
楼上热心人,非常感谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表