C Directory and Subdirectory Recursion - c

I tried to recursively get all files and folder list.But I can only get subdirectories of documents and inside of them.I can't get the other folders which in inside of subdirectory.
I don't know how to do it recursively.I hope you help me
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <windows.h>
#include <unistd.h>
#include <string.h>
void list(char *a);
void reader(char *path);
int
main (void)
{
DIR *dp;
struct dirent *ep;
dp = opendir ("C:\\Users\\pen\\Documents\\");
if (dp != NULL)
{
while (ep = readdir (dp)){
GetFileAttributes(ep->d_name);
if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(ep->d_name))
{
if (strcmp(".",ep->d_name)==0)
continue;
if (strcmp("..",ep->d_name)==0)
continue;
reader(ep->d_name);
}
}
closedir(dp);
}
else
perror ("Couldn't open the directory");
closedir(dp);
system("pause");
return 0;
}
void reader(char *path){
DIR *da;
struct dirent *ef;
da = opendir(path);
while (ef=readdir(da)){
printf ("%s\n",ef->d_name);
if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(ef->d_name))
{
if (strcmp(".",ef->d_name)==0)
continue;
if (strcmp("..",ef->d_name)==0)
continue;
reader(ef->d_name);
}
}
closedir(da);
}

1) In reader you need to call closedir(da); after the while loop.
2) every call to reader needs to have the absolute path you need to concatenate path
to ef->d_name and then call reader.
3) also to enable debugging you should call perror after a failed readdir call.

Related

Trying to create code in C that print all directories starting from a root directory passed

EXAMPLE
Imagine I have a directory called Alpha and I want it as root.
Alpha contains: some files and other two directories Beta and Gamma,
Beta contains: some files and another directory called Theta,
Gamma contains: some files,
Theta contains: some files.
INPUT/OUTPUT
Using input as: ./myfind Alpha
I'll want as output:
Alpha
Beta
Gamma
Theta
(I don't care about the order).
MY CODE
I tried with this code but it doesn't work. I'll want to do a recursive function to do it and i can't use POSIX.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: Run as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char *dir = argv[1];
struct stat statbuf;
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr, "FATAL ERROR: %s IS NOT A DIRECTORY\n", dir);
exit(EXIT_FAILURE);
}
find(dir);
exit(EXIT_SUCCESS);
}
The problem is you change the current directory when you recurse into a subdirectory but you do not change back to the parent directory when returning from the recursive function.
You could add a chdir(".."); at the end of the find function, but it might not work in all cases:
if a directory has more than 2 hard links
if you traverse symbolic links
It is preferable to compute the path of the destination directory for the recursive call to find() by concatenating the passed_dir_name, a / and dir->d_name and avoid changing the current directory.
Here is a modified version of find() for the simplistic approach:
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
chdir("..");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
}

Undefined Reference to 'main' when code is compiled

I created a C program which would create a directory and file.
I have tried to debug the error, but it didn't work
#include <dirent.h>
#include <errno.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
create_dir(char* outputdir,char* str_outpath,char* value){
DIR* dir = opendir(outputdir);
FILE *f;
if (dir) {
/* Directory exists. */
closedir(dir);
} else if (ENOENT == errno) {
/* Directory does not exist. */
mkdir(outputdir, 0700);
closedir(dir);
printf("Successfully created the directory %s ", outputdir);
} else {
printf("Creation of the directory %s failed",outputdir);
/* opendir() failed for some other reason. */
}
f = fopen(str_outpath, "a");
fprintf(f,"%s",value);
fclose(f);
}
I want it to create a file and a directory successfully
As others have mentioned. You do not have a main function.
Also your create_dir function is missing a type. I'll assume it's void since you are not returning anything. This should compile.
#include <dirent.h>
#include <errno.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
void create_dir(char* outputdir,char* str_outpath,char* value){
DIR* dir = opendir(outputdir);
FILE *f;
if (dir) {
/* Directory exists. */
closedir(dir);
} else if (ENOENT == errno) {
/* Directory does not exist. */
mkdir(outputdir, 0700);
closedir(dir);
printf("Successfully created the directory %s ", outputdir);
} else {
printf("Creation of the directory %s failed",outputdir);
/* opendir() failed for some other reason. */
}
f = fopen(str_outpath, "a");
fprintf(f,"%s",value);
fclose(f);
}
int main(){
char directory[] = "/users/me/documents/testdir";
char filepath[] = "testfile";
char data[] = "hello world";
create_dir(directory,filepath,data);
return 0;
}
I did not execute the code to check whether it works. I merely copied and pasted yours and called the function.
In C under most cases you need to have a main function. So in order to run your code you'll need to have something like this (assuming that you want to pass in the parameters from the command-line) underneath that function:
int main(int argc, char *argv[]) {
if (argc < 4) {
printf("Proper Usage is ./program otputdir str_outpath value\n");
return -1;
}
char *outputdir = argv[1];
char *str_outpath = argv[2];
char *value = argv[3];
create_dir(outputdir, str_outpath, value);
return 0;
}
EDIT: fixed an issue with not checking argc

How to move the files from one directory to another in c?

I am creating a project on moving a directory files by creating sub-folders according to their particular type in c. I have made up to creating directories with the help of POSIX library dirent.h for the files having different extension present in the home directory but I don't know how to cut a file from home directory and paste in its particular sub-folder. So please guide me about how can I cut and paste a file from one directory to another in c.
Use rename(DestinationFilepath, SourceFilepath);
For more info check man page http://linux.die.net/man/2/rename
For two different system use cURL library:
http://en.wikipedia.org/wiki/CURL
Code in C:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#define DESTINATION_FOLDER "/home/second/"
#define SOURCE_FOLDER "/home/first/"
void printdir()
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
struct tm *tm;
char src_folder[1024];
char dest_folder[1024];
if ((dp = opendir(SOURCE_FOLDER)) == NULL) {
fprintf(stderr,"cannot open directory: %s\n", SOURCE_FOLDER);
return;
}
chdir(SOURCE_FOLDER);
while ((entry = readdir(dp)) != NULL) {
lstat(entry->d_name, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
sprintf(src_folder, "%s%s", SOURCE_FOLDER, entry->d_name);
sprintf(dest_folder, "%s%s", DESTINATION_FOLDER, entry->d_name);
printf("%s----------------%s\n", entry->d_name, dest_folder);
rename(src_folder, dest_folder);
}
}
chdir("..");
closedir(dp);
}
int main()
{
while (1) {
printdir();
}
rename("aaa.txt", "/home/second/bbb.txt");
printf("done.\n");
exit(0);
}

scan a directory to find files in c

I'm trying to create a function in c which scans all my path C: \ temp (Windows) to search for a file that I pass (eg test.txt) and each time it finds one return the path to steps another function to write something in the bottom of this file.
I managed to do the function that writes to the file but can not figure out how to do that scans the folder and pass the address of the file found.
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
void printdir(char *dir, int depth)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(dir)) == NULL) {
fprintf(stderr,"cannot open directory: %s\n", dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
lstat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode)) {
/* Found a directory, but ignore . and .. */
if(strcmp(".",entry->d_name) == 0 ||
strcmp("..",entry->d_name) == 0)
continue;
printf("%*s%s/\n",depth,"",entry->d_name);
/* Recurse at a new indent level */
printdir(entry->d_name,depth+4);
}
else printf("%*s%s\n",depth,"",entry->d_name);
}
chdir("..");
closedir(dp);
}
int main()
{
printf("Directory scan of /home:\n");
printdir("/home",0);
printf("done.\n");
exit(0);
}
Use FindFirstFile function. Here's a good example of this function using.

Get only the files included in a directory in c / Ubuntu

I have to create a listing of the files contained inside a specific directory, I have done the code below(part of a bigger programm), but I would like my programm to ignore any possible folders that could be included inside the directory.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main ()
{
DIR *dirptr;
struct dirent *entry;
dirptr = opendir ("synchedFolder");
if (dirptr != NULL)
{
while (entry = readdir (dirptr))
{
if(strcmp(entry->d_name,"..")!=0 && strcmp(entry->d_name,".")!=0)
puts (entry->d_name);
}
(void) closedir (dirptr);
}
else
perror ("ERROR opening directory");
}
If you want to list only files, but no directories, you have to add the following check:
entry->d_type == DT_REG
or
entry->d_type != DT_DIR
There's stat() and lstat() and the return value for stat. In the latter, look out for the S_ISDIR macro.
Short answer is the dirent structure includes the necessary information:
if ( entry->d_type == DT_REG)
Check stat (or lstat)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
/* int main (void){ */
int main (int argc, char **argv){
int i,result=0;
struct stat buf;
/* print_S_I_types(); */
for (i=1; i < argc; i++){
if (lstat(argv[i], &buf) < 0) {
fprintf(stderr, "something went wrong with %s, but will continue\n",
argv[i]);
continue;
} else {
if S_ISREG(buf.st_mode){
printf("argv[%d] is normal file\n",i);
}else {
printf("argv[%d] is not normal file\n",i);
}
}
}
return 0;
}
Working code for listing files (without directories):
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
int main()
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir ("/home/images")) != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
if(ent->d_type!= DT_DIR)
{
printf ("%s\n", ent->d_name);
}
}
closedir (dir);
}
else
{
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
}

Resources