如何使用 C 在目录中迭代并在特定级别停止?
How to iterate in a directory and stop at a particular level using C?
我正在尝试在终端中打印系统中当前所有进程的名称。为此,我必须进入 "proc" 目录中所有以进程 ID 命名的目录。所以我一直循环到 "acpi" 目录之前,并尝试读取每个进程目录中的状态文件。但我不完全明白如何读取目录内目录中的文件。在 运行 我的代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, const char *argv[])
{
DIR* FD;
struct dirent* in_file;
FILE *process_file;
char ch, pname[1024];
int i=0;
FD = opendir ("/proc");
while ((in_file = readdir(FD)))
{
if (strcmp (in_file->d_name, "acpi") == 0)
break;
else
{
opendir(in_file->d_name);
process_file = fopen("status", "r");
while( ( ch = fgetc(process_file) ) != '\n' )
{
pname[i] = ch;
i++;
}
printf(" %s \n",pname);
fclose(process_file);
closedir(in_file->d_name);
}
}
closedir(FD);
return 0;
}
我收到错误:
myps.c: In function ‘main’:
myps.c:38:13: warning: passing argument 1 of ‘closedir’ from incompatible pointer type
closedir(in_file->d_name);
^
In file included from myps.c:5:0:
/usr/include/dirent.h:149:12: note: expected ‘struct DIR *’ but argument is of type ‘char *’
extern int closedir (DIR *__dirp) __nonnull ((1));
^
要解决错误,请保存您打开的目录指针。然后用它来关闭目录。
DIR *process_dir = opendir(in_file->d_name);
closedir(process_dir);
这是何时使用递归函数的一个很好的例子。
该函数将获取一个目录名,打开该目录,然后循环遍历结果。对于每个不是 .
或 ..
的结果,调用 stat
函数来获取每个条目的状态。然后对文件模式使用 S_ISREG
和 S_ISDIR
宏来查看它是常规文件还是目录。如果它是一个目录,则从父目录和您刚刚找到的目录构建一个新字符串,并将其传递给递归函数调用。
所以函数看起来像这样:
void processDirectory(char dirname[])
{
struct stat statbuf;
DIR *dir;
struct dirent *de;
char *subdirname;
int rval, ;
if ((dir = opendir(dirname)) == NULL) {
perror("Failed to open directory %s", dirname);
exit(1);
}
while ((errno = 0, de = readdir(dir)) != NULL) {
rval = stat(de->d_name, &statbuf);
if (rval == -1) {
perror("stat failed");
exit(1);
}
if (S_ISREG(statbuf.st_mode)) {
// process as a regular file
} else if (S_ISDIR(statbuf.st_mode)) {
if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
subdirname = malloc(strlen(dirname) + strlen(de->d_name) + 2);
if (subdirname == NULL) {
perror("malloc failed");
exit(1);
}
strcpy(subdirname, dirname);
strcat(subdirname, "/");
strcat(subdirname, de->d_name);
processDirectory(subdirname);
free(subdirname);
}
}
}
if (errno && (errno != ENOENT)) {
perror("Failed to read directory %s", dirname);
exit(1);
}
closedir(dir);
}
我正在尝试在终端中打印系统中当前所有进程的名称。为此,我必须进入 "proc" 目录中所有以进程 ID 命名的目录。所以我一直循环到 "acpi" 目录之前,并尝试读取每个进程目录中的状态文件。但我不完全明白如何读取目录内目录中的文件。在 运行 我的代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, const char *argv[])
{
DIR* FD;
struct dirent* in_file;
FILE *process_file;
char ch, pname[1024];
int i=0;
FD = opendir ("/proc");
while ((in_file = readdir(FD)))
{
if (strcmp (in_file->d_name, "acpi") == 0)
break;
else
{
opendir(in_file->d_name);
process_file = fopen("status", "r");
while( ( ch = fgetc(process_file) ) != '\n' )
{
pname[i] = ch;
i++;
}
printf(" %s \n",pname);
fclose(process_file);
closedir(in_file->d_name);
}
}
closedir(FD);
return 0;
}
我收到错误:
myps.c: In function ‘main’:
myps.c:38:13: warning: passing argument 1 of ‘closedir’ from incompatible pointer type
closedir(in_file->d_name);
^
In file included from myps.c:5:0:
/usr/include/dirent.h:149:12: note: expected ‘struct DIR *’ but argument is of type ‘char *’
extern int closedir (DIR *__dirp) __nonnull ((1));
^
要解决错误,请保存您打开的目录指针。然后用它来关闭目录。
DIR *process_dir = opendir(in_file->d_name);
closedir(process_dir);
这是何时使用递归函数的一个很好的例子。
该函数将获取一个目录名,打开该目录,然后循环遍历结果。对于每个不是 .
或 ..
的结果,调用 stat
函数来获取每个条目的状态。然后对文件模式使用 S_ISREG
和 S_ISDIR
宏来查看它是常规文件还是目录。如果它是一个目录,则从父目录和您刚刚找到的目录构建一个新字符串,并将其传递给递归函数调用。
所以函数看起来像这样:
void processDirectory(char dirname[])
{
struct stat statbuf;
DIR *dir;
struct dirent *de;
char *subdirname;
int rval, ;
if ((dir = opendir(dirname)) == NULL) {
perror("Failed to open directory %s", dirname);
exit(1);
}
while ((errno = 0, de = readdir(dir)) != NULL) {
rval = stat(de->d_name, &statbuf);
if (rval == -1) {
perror("stat failed");
exit(1);
}
if (S_ISREG(statbuf.st_mode)) {
// process as a regular file
} else if (S_ISDIR(statbuf.st_mode)) {
if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
subdirname = malloc(strlen(dirname) + strlen(de->d_name) + 2);
if (subdirname == NULL) {
perror("malloc failed");
exit(1);
}
strcpy(subdirname, dirname);
strcat(subdirname, "/");
strcat(subdirname, de->d_name);
processDirectory(subdirname);
free(subdirname);
}
}
}
if (errno && (errno != ENOENT)) {
perror("Failed to read directory %s", dirname);
exit(1);
}
closedir(dir);
}