计算每个子目录的文件 - C 中的程序 (POSIX)
Counting files for each subdirectory - program in C (POSIX)
我完全是使用 POSIX 进行 C 编程的初学者。
我正在尝试编写一个程序,该程序从环境变量中给定的目录开始计算每个子目录中的文件。对于每个子目录,程序应向标准输出写入一条短消息:
目录:name_of_dir
文件:num_of_files
我试过用 nftw() 编写这样的程序。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define _XOPEN_SOURCE 500
#include <ftw.h>
#define MAXFD 20
int files = 0; // files count for each subdirectory
int files_main = 0; // files count for the directory from env variable DIR
int k = 0;
int l = 0;
char prev_dir[100];
char current_dir[100];
void print_dir() // helper function to print current directory
{
char current_dir[100];
getcwd(current_dir, 100);
printf("Directory: %s \n", current_dir);
}
void print_files() // helper function to print number of files
{
printf("Files: %d \n", files);
}
int search(const char *name, const struct stat *s, int type, struct FTW *f)
{
getcwd(current_dir, 100);
if(strcmp(prev_dir, current_dir) != 0 && l == 1) // check if the directory has changed, l as a flag to omit printing the same directory path more than once
{
l = 0;
print_files();
files = 0;
strcpy(prev_dir, current_dir);
}
if(strcmp(current_dir, getenv("DIR")) == 0) // counting files in directory from env variable DIR
{
switch (type)
{
case FTW_F: files_main++; break;
}
}
else // counting files for each subdirectory
{
getcwd(prev_dir, 100);
if(l==0)
{
print_dir();
l = 1;
}
switch (type)
{
case FTW_F: files++; break;
}
}
return 0;
}
int main(int argc, char ** argv)
{
strcpy(prev_dir, getenv("DIR")); // getting the dir from env variable
nftw(getenv("DIR"), search, depth, FTW_CHDIR);
printf("Directory: %s \n", getenv("DIR"));
printf("Files: %d \n", files_main);
return EXIT_SUCCESS;
}
这是环境变量 "DIR" 中目录的 "find [...] type -f" 的输出:
./.DS_Store
./playground2
./playground3
./playground
./playground.c
./test_dir1/test1.txt
./test_dir1/test2.txt
./Makefile
./playground3.c
./test_file.txt
./playground2.c
./test_dir2/test3.tst
./dir1/p.tet
./dir1/sfsdfsdf/dfsd.txt
./dir1/ofi/test
./dir1/ofi/test2
./link_by_link_function
这是我 运行 C 程序时的输出:
$ ./playground2
Directory: /Users/<user>/Desktop/C POSIX/Playground
Files: 5
Directory: /Users/<user>/Desktop/C POSIX/Playground/test_dir1
Files: 2
Directory: /Users/<user>/C POSIX/Playground
Files: 4
Directory: /Users/<user>/C POSIX/Playground/test_dir2
Files: 1
Directory: /Users/<user>/C POSIX/Playground/dir1
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/Playground/dir1/sfsdfsdf
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/Playground/dir1/ofi
Files: 2
Directory: /Users/<user>/Desktop/C POSIX/Playground
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/test_dir1
Files: 2
Directory: /Users/<user>/Desktop/C POSIX/test_dir2
Files: 1
Directory: /Users/<user>/Desktop/C POSIX
Files: 19
程序未按预期运行,查看输出后很明显。
"files_main" 计数器也工作 [...]/Playground/ 子目录的计数器似乎工作正常。问题是 [...]/Playground/ 目录本身。
计数器 "files" 在检测到目录更改后重置,当程序多次进入 [...]/Playground 目录时,这不是一个好的解决方案(至少这是我在这一点上得出的结论)。
我尝试使用 FTW_CHDIR 和 FTW_DEPTH 标志,但输出仅显示来自环境变量 "DIR" 的目录,其中 count == 0;
在这一点上,我迷路了,不知道如何以不同的方式编写这个程序来完成任务。
任何 ideas/help 将不胜感激 :) .
理想情况下,您希望广度优先搜索 (BFS) 进行计数。使用 BFS,在进入下一个目录(向下或向上)之前处理每个目录。不幸的是,nftw 正在实施深度搜索优先 (DFS)。
您可以使用 FTW
结构(搜索函数的参数 f
)解决计数限制。它包括成员'level'。您可以维护一个计数器数组,每个级别一个。
另请注意,搜索功能已传递足够的信息,因此无需保持状态(current_dir、prev_dir、...)、检测更改等
static int file_count[50] ; // Assuming big enough.
static int search(const char *name, const struct stat *s, int type, struct FTW *f)
{
static int file_count[50] ;
// Count
if ( f->level < 50 ) { file_count[f->level]++ ;} ;
if ( type == FTW_DP ) {
// Last entry for folder
printf("Folder: %s files: %d\n", name, file_count[f->level+1]) ;
file_count[f->level+1] = 0 ;
} ;
return 0 ;
}
main (...)
{
Invoke nftw with FTW_DP
}
链接:
我完全是使用 POSIX 进行 C 编程的初学者。 我正在尝试编写一个程序,该程序从环境变量中给定的目录开始计算每个子目录中的文件。对于每个子目录,程序应向标准输出写入一条短消息:
目录:name_of_dir
文件:num_of_files
我试过用 nftw() 编写这样的程序。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define _XOPEN_SOURCE 500
#include <ftw.h>
#define MAXFD 20
int files = 0; // files count for each subdirectory
int files_main = 0; // files count for the directory from env variable DIR
int k = 0;
int l = 0;
char prev_dir[100];
char current_dir[100];
void print_dir() // helper function to print current directory
{
char current_dir[100];
getcwd(current_dir, 100);
printf("Directory: %s \n", current_dir);
}
void print_files() // helper function to print number of files
{
printf("Files: %d \n", files);
}
int search(const char *name, const struct stat *s, int type, struct FTW *f)
{
getcwd(current_dir, 100);
if(strcmp(prev_dir, current_dir) != 0 && l == 1) // check if the directory has changed, l as a flag to omit printing the same directory path more than once
{
l = 0;
print_files();
files = 0;
strcpy(prev_dir, current_dir);
}
if(strcmp(current_dir, getenv("DIR")) == 0) // counting files in directory from env variable DIR
{
switch (type)
{
case FTW_F: files_main++; break;
}
}
else // counting files for each subdirectory
{
getcwd(prev_dir, 100);
if(l==0)
{
print_dir();
l = 1;
}
switch (type)
{
case FTW_F: files++; break;
}
}
return 0;
}
int main(int argc, char ** argv)
{
strcpy(prev_dir, getenv("DIR")); // getting the dir from env variable
nftw(getenv("DIR"), search, depth, FTW_CHDIR);
printf("Directory: %s \n", getenv("DIR"));
printf("Files: %d \n", files_main);
return EXIT_SUCCESS;
}
这是环境变量 "DIR" 中目录的 "find [...] type -f" 的输出:
./.DS_Store
./playground2
./playground3
./playground
./playground.c
./test_dir1/test1.txt
./test_dir1/test2.txt
./Makefile
./playground3.c
./test_file.txt
./playground2.c
./test_dir2/test3.tst
./dir1/p.tet
./dir1/sfsdfsdf/dfsd.txt
./dir1/ofi/test
./dir1/ofi/test2
./link_by_link_function
这是我 运行 C 程序时的输出:
$ ./playground2
Directory: /Users/<user>/Desktop/C POSIX/Playground
Files: 5
Directory: /Users/<user>/Desktop/C POSIX/Playground/test_dir1
Files: 2
Directory: /Users/<user>/C POSIX/Playground
Files: 4
Directory: /Users/<user>/C POSIX/Playground/test_dir2
Files: 1
Directory: /Users/<user>/C POSIX/Playground/dir1
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/Playground/dir1/sfsdfsdf
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/Playground/dir1/ofi
Files: 2
Directory: /Users/<user>/Desktop/C POSIX/Playground
Files: 1
Directory: /Users/<user>/Desktop/C POSIX/test_dir1
Files: 2
Directory: /Users/<user>/Desktop/C POSIX/test_dir2
Files: 1
Directory: /Users/<user>/Desktop/C POSIX
Files: 19
程序未按预期运行,查看输出后很明显。 "files_main" 计数器也工作 [...]/Playground/ 子目录的计数器似乎工作正常。问题是 [...]/Playground/ 目录本身。 计数器 "files" 在检测到目录更改后重置,当程序多次进入 [...]/Playground 目录时,这不是一个好的解决方案(至少这是我在这一点上得出的结论)。
我尝试使用 FTW_CHDIR 和 FTW_DEPTH 标志,但输出仅显示来自环境变量 "DIR" 的目录,其中 count == 0;
在这一点上,我迷路了,不知道如何以不同的方式编写这个程序来完成任务。
任何 ideas/help 将不胜感激 :) .
理想情况下,您希望广度优先搜索 (BFS) 进行计数。使用 BFS,在进入下一个目录(向下或向上)之前处理每个目录。不幸的是,nftw 正在实施深度搜索优先 (DFS)。
您可以使用 FTW
结构(搜索函数的参数 f
)解决计数限制。它包括成员'level'。您可以维护一个计数器数组,每个级别一个。
另请注意,搜索功能已传递足够的信息,因此无需保持状态(current_dir、prev_dir、...)、检测更改等
static int file_count[50] ; // Assuming big enough.
static int search(const char *name, const struct stat *s, int type, struct FTW *f)
{
static int file_count[50] ;
// Count
if ( f->level < 50 ) { file_count[f->level]++ ;} ;
if ( type == FTW_DP ) {
// Last entry for folder
printf("Folder: %s files: %d\n", name, file_count[f->level+1]) ;
file_count[f->level+1] = 0 ;
} ;
return 0 ;
}
main (...)
{
Invoke nftw with FTW_DP
}
链接: