【问题标题】:calling opendir and readdir is changing my char array调用 opendir 和 readdir 正在改变我的 char 数组
【发布时间】:2012-12-07 00:27:55
【问题描述】:

这是我到目前为止的代码,它找到了根的位置,但是当我添加该行时:

printf("        name: %s\n", readdir(opendir(cur_spot))->d_name);

它改变了 cur_spot 并向它添加了奇怪的字符(文件名:.~?)就是它打印的内容。知道为什么会这样吗?

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    struct stat file_stats;
    struct stat parent_stats;
    struct dirent temp_dir;

    char cwd_name[256]; //directory name
    char cur_spot[256]; //current directory spot

    cur_spot[0] = '.';
    stat(cur_spot, &file_stats);
    printf("filename: %s\n", cur_spot);
    printf(" inode: %ld\n", file_stats.st_ino);


    strcat(cur_spot, ".");
    stat(cur_spot, &parent_stats);
    printf("filename: %s\n", cur_spot);
    printf(" inode: %ld\n", parent_stats.st_ino);

    while(file_stats.st_ino != parent_stats.st_ino) {
        printf("not at root yet\n\n");

        stat(cur_spot, &file_stats);
        printf("    current child\n");
        printf("        inode: %ld\n", file_stats.st_ino);
        printf("        name: %s\n", readdir(opendir(cur_spot))->d_name);
        strcat(cur_spot, "/..");
        stat(cur_spot, &parent_stats);
        printf("    current parent\n");
        printf("        inode: %ld\n", parent_stats.st_ino);
    }
        printf("at root\n");


    return 0;
}

【问题讨论】:

  • 你没有初始化char cur_spot[256];,所以第一个stat(cur_spot, &amp;file_stats);可以统计谁知道什么。
  • 更准确地说,它缺少cur_spot[1] = 0;
  • 或者用char cur_spot[256] = ".";初始化它
  • 不要忘记为您调用的每个 opendir() 调用 closedir()。你必须保存 opendir() 的返回指针才能做到这一点。
  • 我确实有 cur_spot[256] = ".";就像我说的那样,在我添加 open 和 readdir 之前一切正常

标签: c readdir


【解决方案1】:

这在 GCC 上对我来说很好用:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    struct stat file_stats;
    struct stat parent_stats;
    struct dirent temp_dir;
    DIR *dirp;

    char cwd_name[256]; //directory name
    char cur_spot[256]; //current directory spot

    strcpy(cur_spot,".");  // <------------ changed
    stat(cur_spot, &file_stats);
    printf("filename: %s\n", cur_spot);
    printf(" inode: %ld\n", file_stats.st_ino);


    strcat(cur_spot, ".");
    stat(cur_spot, &parent_stats);
    printf("filename: %s\n", cur_spot);
    printf(" inode: %ld\n", parent_stats.st_ino);

    while(file_stats.st_ino != parent_stats.st_ino) {
        printf("not at root yet\n\n");

        stat(cur_spot, &file_stats);
        printf("    current child\n");
        printf("        inode: %ld\n", file_stats.st_ino);
        dirp=opendir(cur_spot); // <----------------added
        printf("        name: %s\n", readdir(dirp)->d_name);  // <----changed
        closedir(dirp); // <------------------------added
        strcat(cur_spot, "/..");
        stat(cur_spot, &parent_stats);
        printf("    current parent\n");
        printf("        inode: %ld\n", parent_stats.st_ino);
    }
        printf("at root\n");


    return 0;
}

【讨论】:

  • 太棒了,这对我也有用。但是,我的印象是 d_name 将返回目录的名称,但它正在打印 .、.bash_logout 或 srv(srv 是根目录的位置)。有什么办法可以让它打印你在使用类似 ls 或类似的东西时看到的内容?
  • @TroyCosentino - 已经有一段时间了,我现在没有时间深入研究它,但我认为你一直在调用 readdir(),它会继续给你下一个每次调用时目录中的文件。我不记得目录结束条件是什么。你有可用的man 命令吗?
  • @TroyCosentino - 查看我的新答案,了解我认为您想要的其他更改。
【解决方案2】:

您应该在字符数组的末尾添加一个 NULL 字符。

错误:

cur_spot[0] = '.';

对:

cur_spot[0] = '.';
cur_spot[1] = '\0';

NULL 字符终止一个字符串。默认情况下,字符串可能会或可能不会初始化为 NULL。

【讨论】:

    【解决方案3】:

    你在一个循环中做了一堆“opendir”,但我没有看到“closedir”的痕迹。你应该受到惩罚……

    【讨论】:

      【解决方案4】:

      这超出了您最初问题的范围,因此我将其添加为与第一个问题不同的答案。正如我在我的第一个答案下的评论中所说,如果您要打印目录中所有文件的文件名,您只需继续调用 readdir() 直到某个终止条件,从阅读手册页来看,这只是一个 NULL 返回价值。顺便说一句,如果您的手册页显示 READDIR(2)This is not the function you are interested in,您真正想做的是查看 readdir 上的第 3 节手册页,您可以使用 man -s 3 readdir 获得。

      无论如何,我修改了我的第一个答案中的代码来做我认为你想要的:

      #include <time.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <dirent.h>
      #include <sys/stat.h>
      #include <sys/types.h>
      
      int main(int argc, char *argv[]) {
          struct stat file_stats;
          struct stat parent_stats;
          struct dirent temp_dir;
          DIR *dirp;
          struct dirent* dent;
      
          char cwd_name[256]; //directory name
          char cur_spot[256]; //current directory spot
      
          strcpy(cur_spot,".");          // <------------- changed
          stat(cur_spot, &file_stats);
          printf("filename: %s\n", cur_spot);
          printf(" inode: %ld\n", file_stats.st_ino);
      
      
          strcat(cur_spot, ".");
          stat(cur_spot, &parent_stats);
          printf("filename: %s\n", cur_spot);
          printf(" inode: %ld\n", parent_stats.st_ino);
      
          while(file_stats.st_ino != parent_stats.st_ino) {
              printf("not at root yet\n\n");
      
              stat(cur_spot, &file_stats);
              printf("    current child\n");
              printf("        inode: %ld\n", file_stats.st_ino);
              dirp=opendir(cur_spot);    // <------------- added
              do {                       // <------------- NEW
                  dent = readdir(dirp);  // <------------- NEW
                  if (dent)              // <------------- NEW
                      printf("        name: %s\n", dent->d_name);
              } while (dent);            // <------------- NEW
              closedir(dirp);            // <------------- added
              strcat(cur_spot, "/..");
              stat(cur_spot, &parent_stats);
              printf("    current parent\n");
              printf("        inode: %ld\n", parent_stats.st_ino);
          }
              printf("at root\n");
      
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-22
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-16
        • 2011-05-15
        • 2015-06-06
        • 1970-01-01
        相关资源
        最近更新 更多