Click here to Skip to main content
15,889,281 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C++
char path[PATH_MAX] = "";
char path1[PATH_MAX];

void listdir(void){
    DIR *dir;
    struct dirent *entry;
    if (!(dir = opendir(path))) {  
        perror ("opendir-path not found");
        return;
    }

    while ((entry = readdir(dir))) {  
        char *name = entry->d_name;
        if (entry->d_type == DT_DIR)  
            if (!strcmp(name, ".") || !strcmp(name, ".."))
                continue;
        snprintf (path1, 100, "%s/%s\n", path, name);

        if (entry->d_type == DT_DIR) {
            char *p; 
            strcat (path, "/");
            strcat (path, name);
            listdir();
            if ((p = strrchr (path, '/'))) {
                if (p != path)        
                    *p = 0;          
            }
        }
    }
    char *token1 = strtok(path1, "\n");
    char *token2 = strtok(NULL, "\n");
    printf("%s\n", token2);
    closedir (dir); 
}

int main (int argc, char **argv) {  
    if (argc > 1)
        strcpy (path, argv[1]);
    else
        strcpy(path, "/home/runner/TestC1");   
    listdir();
}


What I have tried:

I am working on monitoring the filesystem project. So I decided to take each pathname and add it to inotify_add_watch one by one to monitor them. But the problem is that whenever I try to split the pathname with the difference of newline "\n", the token1 variable prints all the pathnames. Although it should only print the first pathname and token2 prints the null number of times(depends on the number of pathnames).

Note: I put the delimiter "\n". You can put space or anything. But none of them gave me the required result.
Posted
Updated 17-Feb-21 7:43am
v2
Comments
k5054 17-Feb-21 12:17pm    
Maybe you could explain a bit more about what you are trying to get at the end of this? For example given the following directory structure:
/home/TestC1/
|-- able/
|-- baker/
|   |-- alpha/
|   |-- beta/
|   `-- gamma/
`-- charlie/
What should the output be? Did you want just the last path element, the whole thing, anything after the base (/home/TestC1 in this case), or ???

I think your first mistake is using a global variable with a recursive function. That is really, really bad idea.

The path variable should ALWAYS be passed into the function. When you encounter a directory you should make a local variable to hold the new directory path and then pass THAT one into the function.

Also - path1 should not be global either. It should be local to the listdir function. You should do everything you possibly can to avoid using global variables. This is one example of why.

Lastly, in main you should make a local variable, put the path name into it, and pass that into listdir. There is no need what so ever to have any global variables in this.
 
Share this answer
 
v2
Comments
KarstenK 17-Feb-21 14:13pm    
"bad idea" a polite description ;-)
Rick York 17-Feb-21 16:21pm    
I try. Usually. :)
Maybe ftw() is a better fit? e.g.:
C
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <ftw.h>
#include <string.h>

int display(const char *full_path, const struct stat *sb, int tflag, struct FTW *ftwb)
{
    if(tflag == FTW_D) {
        const char *child_path = strchr(full_path, '/');
        if(child_path == NULL)
            child_path = "";
        else
            child_path += 1;
        printf("%s -> '%s', '%s'\n",
               full_path,       /* the etire path */
               child_path,      /* portion after first directory */
               full_path+ftwb->base ); /* last element in path */
    }

    return 0;
    (void)sb; /* parameter "usage", silences compiler warning */

}

int main(int argc, char *argv[])
{
    if(nftw(argv[1], display, 20, 0) == -1) {
        perror("nftw");
        return 1;
    }

    return 0;
    (void)argc;
}

Also note we're not using strtok(), which I think is part of your problem. strto() uses the second argument as a list of characters to break the string on, so
C
strtok(path, "\n")
looks for a new-line char, replaces that with a nul ('\0') and returns a pointer to the beginning of the string. At best you want
C
strtok(path, "/")
which looks for a forward-slash.
Note also that ftw() omits the . and .. directories for you
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900