2012-07-17 67 views
3

我一直在检查和战斗这个程序没有成功很长一段时间,希望你能帮助我。使用readdir_r阅读目录

这个想法是读取存储在c_Localpath中的目录,并将读取的目录复制到c_namesLocal以返回它们。

我在执行中做错了什么?该程序打破了strcpy,我不知道为什么。

DIR* ptr_dir = opendir(c_Localpath); 

char** c_namesLocal = calloc(1, 256); 

    size_t numElements = 0; 
    int returnCode =0; 
    struct dirent ptr_PrevDirEntry; 
    struct dirent* ptr_DirEntry = NULL; 
    returnCode = readdir_r(ptr_dir, &ptr_PrevDirEntry, 
      &ptr_DirEntry); 

    while ((returnCode ==0) && (ptr_DirEntry != NULL)) { 
     char* name = c_namesLocal[numElements]; 
     strcpy(name, ptr_DirEntry->d_name); 
     ptr_PrevDirEntry = *ptr_DirEntry; 
     returnCode = readdir_r(ptr_dir, &ptr_PrevDirEntry, 
       &ptr_DirEntry); 
     numElements++; 
     c_namesLocal = realloc(c_namesLocal, 256 * numElements); 
    } 

回答

0

这是一个零指示字例外,c_namesLocal实际上指向256 /的sizeof(字符*)的char *指针全部由释放calloc设置为空,所以c_namesLocal[numElements] == 0的序列。您必须为每个条目分配内存。

+0

非常感谢您的回答,但我没有完全得到它,我应该如何分配,否则比realloc? – 2012-07-17 22:17:11

0

在此代码:

char* name = c_namesLocal[numElements]; 
strcpy(name, ptr_DirEntry->d_name); 

name开始为NULL。您初始化了指针的一个向量,但单指针本身仍然指向NULL。你应该分配内存d_name:当你的realloc指针的矢量

if (NULL == (c_namesLocal[numElements] = strdup(ptr_DirEntry->d_name))) 
{ 
    // signal out of memory and return 
} 

而同样的检查:

// You no longer need '*name' 
c_namesLocal[numElements] = strdup(ptr_DirEntry->d_name); 

然后,它会谨慎地添加检查。

5

对不起,2年后回复。但我想帮助那些想知道答案的人。 我一直在执行readdir_r,因此我修改了您的代码以使其工作。我不能说整个代码都可以工作,但可以确定的是,您可以在您提到的指定目录中获得下一个文件条目。因此,您可以将这些条目保存到其他变量中,并可以做任何您想要的操作。

请参阅下文。

DIR* ptr_dir = opendir(c_Localpath); 
size_t numElements = 0; 
int returnCode =0; 
struct dirent *ptr_PrevDirEntry = NULL; 
struct dirent *ptr_DirEntry = NULL; 
int len_entry; 
char *c_namesLocal = NULL; 

len_entry = offsetof(struct dirent, d_name) + fpathconf(dirfd(ptr_dir), _PC_NAME_MAX) + 1; 
ptr_PrevDirEntry = malloc(len_entry); 

if(!ptr_PrevDirEntry) 
     exit(0); 

for(;;){ 
     readdir_r(ptr_dir, ptr_PrevDirEntry, &ptr_DirEntry); 
     if(!ptr_DirEntry) 
      break; 
     else 
     { 
       if((strcmp(ptr_DirEntry->d_name, ".") != 0) && (strcmp(ptr_DirEntry->d_name, "..") != 0)) // skip "." and ".." file listings 
       { 
        //Perform copying or do whatever you want with the file entry read from the dir "c_Localpath" 
        //Increase numElements to 1 and keep on increasing by 1 on every iteration 
        numElements++; 
        //realloc everytime you find next entry 
        c_namesLocal = realloc(c_namesLocal, 256 * numElements); 
        //copy the next file name in the c_namesLocal[0], c_namesLocal[1] and so on. 
        strcpy(c_namesLocal[numElements - 1], ptr_DirEntry->d_name); 
       } 
     } 
} 

//free "ptr_PrevDirEntry" before returning and take care of "c_namesLocal" as well. 

上面的代码是不言自明的。我希望它能帮助你。欢呼:)

+0

'if(strlen(ptr_DirEntry)> 2)'会比这个跳过更多。 – 2014-12-24 13:55:46

+0

修改代码。感谢您指出。 :) – Rohit 2014-12-26 05:13:31

+0

我想在Visual Studio中使用readdir_r函数。你有什么想法,我该怎么做? – 2016-07-20 11:12:01