对于代码的一部分,我需要将给定目录中每个文件的名称和统计信息(用户ID、组ID、修改时间、权限等)保存到一个自定义结构的数组中。将信息保存到数组中是可以的,所以为了清楚起见,我把这些东西省略了。我遇到的问题是预定义的struct stat
:在测试中,它为目录中的每个文件打印出相同的确切修改日期,这是一个问题,而日期来自1969,这是另一个问题(考虑到我清楚地记得去年某个时候创建和修改了这些文件)。我不确定哪里出了问题;如能得到帮助,将不胜感激。
注意:这是我第一次用C编程,所以如果有任何明显的错误,请告诉我。我的教授非常热衷于独立研究,并没有涵盖所有需要知道的重要事情。此外,我意识到我需要检查错误——这些检查已经写好了,将在稍后实现。在我担心所有的错误检查之前,我只需要修复这段代码的晴天部分,所以请不要告诉我这是我的问题。我总是给它一个简单易懂的目录。它应该没有问题打开或阅读。
int main ()
{
DIR *myDIR;
struct dirent *mydirent = malloc(sizeof(struct dirent)); //necessary?
struct stat mystat;
myDIR = opendir(pathname);
int count = 0;
while ((mydirent = readdir(myDIR)) != NULL)
count++;
rewinddir(myDIR);
struct file_info **file_info_array = malloc(sizeof(struct file_info*)*(count+1));
int i = 0;
while ((mydirent = readdir(myDIR)) != NULL)
{
stat(mydirent->d_name, &mystat);
printf("name: %sn", mydirent->d_name);
printf("mod_time: %sn", ctime(&mystat.st_mtime));
/*
... saving file info into file_info_array
*/
}
int is_closed = closedir(myDIR);
/*
... freeing pointers
*/
return 0;
}
将评论转换为答案
您没有检查stat()
是否成功;你不能推迟错误检查——这是不理智/不安全的。如果失败,则不能保证stat
结构的内容是合理的。你还没有展示pathname
是如何设置的。如果pathname不是.
(或.
的同义词),那么stat()
调用将失败;您需要将readdir()
返回的名称转换为相对于pathname
的名称—例如:
char path[PATH_MAX]; /* <limits.h> - if it is defined at all */
snprintf(path, sizeof(path), "%s/%s", pathname, mydirent->d_name);
if (stat(path, &mystat) == 0)
{
…go ahead with printing, etc…
}
哦,天哪,这就是原因!它需要是一个完整的路径吗?这是有道理的,但由于某些原因,当其他同学编码它时,他们按照我最初的方式实现它,即
mydirent->d_name
,并且没有问题。我想知道为什么?
不一定是完整路径;只是一条可以找到的路。如果您只执行stat(mydirent->d_name, &mystat)
,那么您将在当前目录中查找具有给定名称的文件—而不是读取该名称的目录(除非该目录恰好是.
)。也许同学用的是chdir(pathname)
?或者他们只使用.
(或.
的同义词)作为路径名?
那么,它是如何成功地打印出所有的名称,即使它们只存在于输入目录中,而不是我当前的目录中?我不是想和你争论;我只是真的很好奇
stat()
和dirent
是如何工作的。
readdir()
读取名称(仅;没有路径信息)从pathname
命名的目录。所以它可以被打印出来。一般来说,stat()
会失败,因此您会得到垃圾来打印从中获得的信息。
John Bollinger评论:
另一方面,不,没有必要仅仅因为声明了一个可以指向struct dient的变量就为它设置malloc()空间。在安全地解除对变量的引用之前,确实需要给它赋一个有效值,但是可以通过赋readdir()的返回值来实现,假设readdir()成功。-
正如John Bollinger所说,malloc()
是不必要的,更糟糕的是,它是一个内存泄漏。