【问题标题】:Imitating ls in ansi C在 ansi C 中模仿 ls
【发布时间】:2011-12-07 20:24:55
【问题描述】:

我有一个代码可以在 ansi C 中模仿 ls -la,但是当我将目录从 . (当前目录)到任何其他它一直说没有这样的文件或目录,有什么想法吗?

代码:

DIR * mydir;
struct dirent * mydirent;
struct stat st;
char outstr[100];
struct tm *tmp;
mydir = opendir("..");
while ((mydirent=readdir(mydir))!=NULL)
  if ( stat(mydirent->d_name,&st) != -1 ) {
    tmp = localtime(&st.st_mtime);
    if (tmp == NULL)
      perror("localtime ERROR: ");
    else {
      strftime(outstr, sizeof(outstr), "%d/%m/%Y", tmp);
      printf("%o\t%d\t%d\t%d\t%d\t%s\t%s\n",
    st.st_mode, st.st_nlink, st.st_uid, st.st_gid, 
    st.st_size, outstr, mydirent->d_name);
    }
  } 
  else 
    perror("stat ERROR: ");
closedir(mydir);

【问题讨论】:

  • 你考虑过使用调试器吗?
  • 您的标题具有误导性,您的问题与您使用的特定 C 版本无关。我认为“重新实现 POSIX ls”会更好。
  • @JensGustedt:它 ANSI C...我们习惯在这里一直声明c++03、c89、c99、c++0x,以避免混淆
  • opendir("..") 打开父目录。您不希望 (".") 用于当前目录吗?
  • 感谢您的回答 =) cnicutar 是对的 我忘记添加完整路径,抱歉给您带来麻烦,感谢@sehe 的澄清

标签: c linux ls


【解决方案1】:

正如@cnicutar 所述,问题是stat 想要dir/file 形式的文件名。问题是:

  • / 可能无法在所有操作系统上运行。
  • 您需要为组合字符串分配内存,进行溢出检查...

如果您不坚持使用 ANSI 而可以使用 POSIX,那么您可以尝试fstatatdirfd

int dirfd(DIR *dirp);    // convert DIR * from opendir() to dirhandle
int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags);

对于fstatatpathname 是相对于目录句柄的,您可以将pathname 直接指向struct dirent.d_name

【讨论】:

    【解决方案2】:

    您需要将目录路径和文件名连接起来。

    stat(mydirent->d_name,&st) /* d_name is just the name, not the full path. */
    

    使用s(n)printf 或类似的东西:

    sprintf(fullpath, "%s/%s", dirpath, mydirent->d_name);
    stat(fullpath, &st);
    

    【讨论】:

    • 谢谢,没看到 =) 一双新的眼睛看着你自己的代码总是很棒,因为 =)
    • 如果您有时间和好心,我还有一个问题...您知道如何区分文件和文件夹吗?
    • @Saikios S_ISDIR(mydirent->st_mode);
    • 谢谢,提示 =) 它像这样工作 =) if(S_ISDIR(st.st_mode)) printf("I'm a directory");借条两个答案现在:)
    猜你喜欢
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多