Hi, here is a simple puzzle I wanted to discuss.
A C program to take directory name as command line argument and
print last 3 directories and 3 files in all subdirectories without using
api 'system' inside it.
suppose directory bond0 contains
bond1, di2, bond3, bond4, bond5 and my_file1, my_file2, my_file3, my_file4, my_file5, my_file6
and
bond1 contains bond6 my_file7 my_file8 my_file9 my_file10
program should output -
bond3, bond4, bond5, my_file4, my_file5, my_file6, bond6, my_file8, my_file9, my_file10
My code for the above problem is here
#include<dirent.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<stdio.h>
char *directs[20], *files[20];
int i = 0;
int j = 0;
int count = 0;
void printdir(char *);
int count_dirs(char *);
int count_files(char *);
int main()
{
char startdir[20];
printf("Scanning user directories\n");
scanf("%s", startdir);
printdir(startdir);
}
void printdir(char *dir)
{
printf("printdir called %d directory is %s\n", ++count, dir);
DIR *dp = opendir(dir);
int nDirs, nFiles, nD, nF;
nDirs = 0;
nFiles = 0;
nD = 0;
nF = 0;
if (dp) {
struct dirent *entry = 0;
struct stat statBuf;
nDirs = count_dirs(dir);
nFiles = count_files(dir);
printf("The no of subdirectories in %s is %d \n", dir, nDirs);
printf("The no of files in %s is %d \n", dir, nFiles);
while ((entry = readdir(dp)) != 0) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char *filepath =
malloc(strlen(dir) + strlen(entry->d_name) + 2);
if (filepath) {
sprintf(filepath, "%s/%s", dir, entry->d_name);
if (lstat(filepath, &statBuf) != 0) {
}
if (S_ISDIR(statBuf.st_mode)) {
nD++;
if ((nDirs - nD) < 3) {
printf("The directory is %s\n",entry->d_name);
}
} else {
nF++;
if ((nFiles - nF) < 3) {
printf("The files are %s\n",
entry->d_name);
} //if
} //else
free(filepath);
} //if(filepath)
} //while
while ((entry = readdir(dp)) != 0) {
if (strcmp(entry->d_name, ".") == 0
|| strcmp(entry->d_name, "..") == 0) {
continue;
}
printf("In second while loop *entry=%s\n",entry->d_name);
char *filepath =
malloc(strlen(dir) + strlen(entry->d_name) + 2);
if (filepath) {
sprintf(filepath, "%s/%s", dir, entry->d_name);
if (lstat(filepath, &statBuf) != 0) {
}
if (S_ISDIR(statBuf.st_mode)) {
printdir(entry->d_name);
}
} //else
free(filepath);
} //2nd while
closedir(dp);
}
else {
fprintf(stderr, "Error, cannot open directory %s\n", dir);
}
} //printdir
int count_dirs(char *dir)
{
DIR *dp = opendir(dir);
int nD;
nD = 0;
if (dp) {
struct dirent *entry = 0;
struct stat statBuf;
while ((entry = readdir(dp)) != 0) {
if (strcmp(entry->d_name, ".") == 0
|| strcmp(entry->d_name, "..") == 0) {
continue;
}
char *filepath =
malloc(strlen(dir) + strlen(entry->d_name) + 2);
if (filepath) {
sprintf(filepath, "%s/%s", dir, entry->d_name);
if (lstat(filepath, &statBuf) != 0) {
fprintf(stderr, "File Not found? %s\n",
filepath);
}
if (S_ISDIR(statBuf.st_mode)) {
nD++;
} else {
continue;
}
free(filepath);
}
}
closedir(dp);
} else {
fprintf(stderr, "Error, cannot open directory %s\n", dir);
}
return nD;
}
int count_files(char *dir)
{
DIR *dp = opendir(dir);
int nF;
nF = 0;
if (dp) {
struct dirent *entry = 0;
struct stat statBuf;
while ((entry = readdir(dp)) != 0) {
if (strcmp(entry->d_name, ".") == 0
|| strcmp(entry->d_name, "..") == 0) {
continue;
}
char *filepath =
malloc(strlen(dir) + strlen(entry->d_name) + 2);
if (filepath) {
sprintf(filepath, "%s/%s", dir, entry->d_name);
if (lstat(filepath, &statBuf) != 0) {
fprintf(stderr, "File Not found? %s\n",
filepath);
}
if (S_ISDIR(statBuf.st_mode)) {
continue;
} else {
nF++;
}
free(filepath);
}
}
closedir(dp);
} else {
fprintf(stderr, "Error, cannot open file %s\n", dir);
}
return nF;
}
The above code I wrote is a bit not functioning correctly can some one help me to understand the error which is coming.So that I improve it further.There seems to be some small glitch which is not clear to me right now.