Обход каталогов в C
Я пытался найти этот вопрос, но не смог найти удовлетворительного ответа. Итак, вот мой вопрос:
Я перебираю каталоги со следующими вариантами кода:
Я.
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
void traverseDirectory(char name[100]){
DIR* dir;
struct dirent *ent;
struct stat states;
dir = opendir(name);
while((ent=readdir(dir)) != NULL){
stat(ent->d_name,&states);
if(!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name)){
continue;
}
else{
printf("%s/%s\n",name,ent->d_name);
if(S_ISDIR(states.st_mode)){
strcat(name,"/");
strcat(name,ent->d_name);
traverseDirectory(name);
}
}
}
closedir(dir);
}
int main(){
char path[100];
printf("Enter the path:\n");
scanf("%s",&path);
traverseDirectory(path);
}
Он проходит через подкаталоги, но дает ошибку сегментации после прохождения через первый подкаталог и печати его файлов.
Выход:
Enter the path:
/home/harshad/dump
/home/harshad/dump/TraverseDirectory.c
/home/harshad/dump/temp
/home/harshad/dump/temp/temptest.txt
Segmentation fault
II.
#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
void traverseDirectory(char name[100]){
DIR* dir;
struct dirent *ent;
struct stat states;
dir = opendir(name);
while((ent=readdir(dir)) != NULL){
stat(ent->d_name,&states);
if(!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name)){
continue;
}
else{
printf("%s/%s\n",name,ent->d_name);
if(S_ISDIR(ent->d_type & DT_DIR)){
strcat(name,"/");
strcat(name,ent->d_name);
traverseDirectory(name);
}
}
}
closedir(dir);
}
int main(){
char path[100];
printf("Enter the path:\n");
scanf("%s",&path);
traverseDirectory(path);
}
Он печатает все файлы и подкаталоги в данном каталоге, но не перемещается в подкаталогах. Это вывод:
Enter the path:
/home/harshad/dump
/home/harshad/dump/TraverseDirectory.c
/home/harshad/dump/temp
/home/harshad/dump/TraverseDirectory1.out
/home/harshad/dump/dump
/home/harshad/dump/test.txt
/home/harshad/dump/SortMarks.c
/home/harshad/dump/TraverseDirectory.out
/home/harshad/dump/TraverseDirectoryTemp.out
/home/harshad/dump/TraverseDirectory1.c
/home/harshad/dump/TraverseDirectoryTemp.c
/home/harshad/dump/FindEven.c
Здесь dump & temp - это подкаталоги, каждый из которых содержит несколько файлов. Сначала я подумал, что из-за разрешений пользователей он может не проходить в подкаталогах (так как они созданы и принадлежат пользователю root), но, как вы можете видеть из результатов 1-й программы, это не так. Поэтому я не могу понять проблемы с обеими программами. PS: в выходных данных после первых двух строк программа печатает каталоги и файлы.
2 ответа
Вы должны действительно проверить на наличие ошибок в opendir()
, Если это не удастся, он вернется NULL
и затем следующий readdir()
будет сег-вина.
Этого может быть достаточно:
dir = opendir(name);
if (!dir)
{
perror(name);
return;
}
Вы объединяете каждое имя файла с именем, переданным с этим:
strcat(name,ent->d_name);
но не отменяя это готово к следующему файлу. Таким образом, строка становится все длиннее и длиннее, пока не нарушит свой выделенный размер.
Вы должны создать другую строку локально, чтобы сохранить переданное имя.
char localname[100];
strcpy(localname, name);
strcat(localname,"/");
strcat(localname,ent->d_name);
traverseDirectory(localname);
но с лучшей защитой от ошибок, чем я использовал.