我对fts(3)
有疑问。每当我尝试访问fts_children()
函数的任何成员时,我都会遇到分段错误。当我在http://www.kernel.org/doc/man-pages/online/pages/man3/fts.3.html阅读手册页时,它声称在读取函数运行后填充自己并返回通过结构中的link
字段链接的链接列表。我的怀疑是child_function没有返回任何内容,但我觉得这不符合手册页。我应该将这些文件添加到子缓冲区,因为我认为这是自动完成的吗?我的代码如下,
谢谢!
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fts.h>
#include<string.h>
int compare (const FTSENT**, const FTSENT**);
int main(int argc, char* const argv[])
{
FTS* file_system = NULL;
FTSENT* child = NULL;
FTSENT* parent = NULL;
FTSENT* temp = NULL;
file_system = fts_open(argv + 1,FTS_COMFOLLOW | FTS_NOCHDIR,&compare);
while( (parent = fts_read(file_system)) != NULL)
{
child = fts_children(file_system,0);
printf("%s\n", child->fts_path);
}
// while (child ->fts_link != NULL)
// child = child->fts_link;
fts_close(file_system);
return 0;
}
int compare(const FTSENT** one, const FTSENT** two){
return (strcmp((*one)->fts_name, (*two)->fts_name));
}
"test_fs.c" 43L, 1108C
答案 0 :(得分:5)
如果您只对遍历指定路径的所有目录和文件感兴趣,只需重复调用fts_read
即可。
如果您只想遍历流,@ sehe的示例可以重写为:
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<fts.h>
#include<string.h>
#include<errno.h>
int compare (const FTSENT**, const FTSENT**);
void indent (int i);
int main(int argc, char* const argv[])
{
FTS* file_system = NULL;
FTSENT *node, = NULL;
if (argc<2)
{
printf("Usage: %s <path-spec>\n", argv[0]);
exit(255);
}
file_system = fts_open(argv + 1,FTS_COMFOLLOW|FTS_NOCHDIR,&compare);
if (NULL != file_system)
{
while( (node = fts_read(file_system)) != NULL)
{
switch (node->fts_info)
{
case FTS_D :
case FTS_F :
case FTS_SL:
indent(node->fts_level);
printf("%s\n", node->fts_name);
break;
default:
break;
}
}
fts_close(file_system);
}
return 0;
}
int compare(const FTSENT** one, const FTSENT** two)
{
return (strcmp((*one)->fts_name, (*two)->fts_name));
}
void indent(int i)
{
for (; i > 0; i--)
printf(" ");
}
当你运行它时,它会遍历流并按顺序列出所有文件和目录:
★ mkdir -p test/A/1 test/A/2 test/B/1 test/B/2
★ tree test
test
├── A
│ ├── 1
│ └── 2
└── B
├── 1
└── 2
★ ./fts test
test
A
1
2
B
1
2
仅当您需要特定目录的子节点列表时才调用fts_children
。在这种情况下,您必须至少致电fts_read
一次,然后再致电fts_children
;否则fts_children
只会将argv
参数中指定的节点返回fts_open
。
答案 1 :(得分:2)
您只需添加一个NULL检查。
你可能想要
file_system
添加更多错误处理:
fts_children()
函数返回指向FTSENT
结构的指针,该结构描述目录中NULL
终止的链接文件列表中的第一个条目,如果成功的话。fts_children()
函数可能会失败,并为errno
,chdir()
,malloc()
,opendir()
和{{的任何错误设置readdir()
1}}函数指定。
更新到评论中的新问题:
当你在它时:
stat()
示例输出片段:
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fts.h>
#include<string.h>
#include<errno.h>
int compare (const FTSENT**, const FTSENT**);
int main(int argc, char* const argv[])
{
FTS* file_system = NULL;
FTSENT* child = NULL;
FTSENT* parent = NULL;
if (argc<2)
{
printf("Usage: %s <path-spec>\n", argv[0]);
exit(255);
}
file_system = fts_open(argv + 1,FTS_COMFOLLOW | FTS_NOCHDIR,&compare);
if (NULL != file_system)
{
while( (parent = fts_read(file_system)) != NULL)
{
child = fts_children(file_system,0);
if (errno != 0)
{
perror("fts_children");
}
while ((NULL != child)
&& (NULL != child->fts_link))
{
child = child->fts_link;
printf("%s%s\n", child->fts_path, child->fts_name);
}
}
fts_close(file_system);
}
return 0;
}
int compare(const FTSENT** one, const FTSENT** two)
{
return (strcmp((*one)->fts_name, (*two)->fts_name));
}