Я новичок в C и пытаюсь просмотреть все каталоги / файлы из текущего рабочего каталога и вывести их информацию.Проблема, с которой я сталкиваюсь и которую я не могу придумать, - это хороший способ ее решения: если в одной директории есть две папки, во второй раз путь создается неправильно.Например, если dir1 и dir2 находятся на одном и том же пути после того, как «/ что-то / dir1» завершено, путь должен стать «/ что-то / dir2», но становится «/ что-то / dir1 / dir2» из-за того, как я пишу вещи.Я думал о том, чтобы просто отследить предыдущий путь, но я не уверен, как это сделать без постоянного перезаписи каждого рекурсивного вызова.
Обновление: с тех пор я исправил исходную ошибкуи решил, что я опубликую свой новый код здесь.Уловка, о которой я не знал, была opendir ("."), А changeir ("..") фактически перевел бы период в полный текущий или предыдущий путь.Что касается замены операторов type = 8 и type = 4 на более читаемые операторы S_ISDIR (statbuf.st_mode) и S_ISREG (statbuf.st_mode), они, похоже, не работают вообще, в то время как операторы типа работают.Не уверен, что не так с синтаксисом и способом, которым я пытался их использовать.
Обновление 2: я решил проблему S_ISDIR / S_ISREG здесь - Как использовать макросы POSIX S_ISREG () и S_ISDIR ()?
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
void helper(DIR *, struct dirent *, struct stat, char *, int);
void dircheck(DIR *, struct dirent *, struct stat, char *, int);
int main(int argc, char *argv[]){
DIR *dip;
struct dirent *dit;
struct stat statbuf;
char currentPath[FILENAME_MAX];
int depth = 0; /*Used to correctly space output*/
dip = opendir(".");
getcwd(currentPath, FILENAME_MAX);
while((dit = readdir(dip)) != NULL){
/*Skips . and ..*/
if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
continue;
stat(currentPath, &statbuf);
/*Checks if current item is of the type file (type 8)*/
if(dit->d_type == 8)
printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);
/*Checks if current item is of the type directory (type 4)*/
if(dit->d_type == 4)
dircheck(dip, dit, statbuf, currentPath, depth);
}
return 0;
}
/*Recursively called helper function*/
void helper(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
int i = 0;
dip = opendir(currentPath);
while((dit = readdir(dip)) != NULL){
if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
continue;
stat(currentPath, &statbuf);
if(dit->d_type == 8){
for(i = 0; i < depth; i++)
printf(" ");
printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);
}
if(dit->d_type == 4)
dircheck(dip, dit, statbuf, currentPath, depth);
}
}
void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
int i = 0;
strcat(currentPath, "/");
strcat(currentPath, dit->d_name);
/*If two directories exist at the same levelt the path
is built wrong and needs to be corrected*/
if((chdir(currentPath)) == -1){
chdir("..");
getcwd(currentPath, FILENAME_MAX);
strcat(currentPath, "/");
strcat(currentPath, dit->d_name);
for(i = 0; i < depth; i++)
printf (" ");
printf("%s (subdirectory)\n", dit->d_name);
depth++;
helper(dip, dit, statbuf, currentPath, depth);
}
else{
for(i =0; i < depth; i++)
printf(" ");
printf("%s (subdirectory)\n", dit->d_name);
chdir(currentPath);
depth++;
helper(dip, dit, statbuf, currentPath, depth);
}
}