Hmmmmm Hmmmmm - 2 months ago 11
Linux Question

printing line like tree command

I am trying to learn C programming for a task at work and I have set myself a little project, which consists of reading down a file tree including all the sub directories obtaining information about each file.

The problem I couldn't solve is that how to make line when print all the directories as real tree command does.

and this is my sample code:

enum { doSkip, isFile, isDir } testDir(char *path, char *name)
{
struct stat st_buf;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
return doSkip;
}
stat(path, &st_buf);
if (S_ISDIR(st_buf.st_mode))
return isDir;
return isFile;
}

void list(const char *path, int indentlevel)
{
DIR *dirp = opendir(path);
struct dirent *dentry;
char buf[1024];
if (!dirp) {
printf("%*sNo access\n",indentlevel,"");
return;
}

while ((dentry = readdir(dirp)) != NULL) {

sprintf(buf,"%s/%s", path, dentry->d_name);
switch (testDir(buf,dentry->d_name)) {
case doSkip:
/* do nothing */
break;
case isDir:
printf("%*s%s:\n",indentlevel,"",dentry->d_name);
list(buf,indentlevel+4);
break;
case isFile:
printf("%*s%s\n",indentlevel,"",dentry->d_name);
break;
}
}
closedir(dirp);
}

int main()
{
list(".", 0);
return 0;
}


please give me some idea!

Answer
list(buf,indentlevel+4);

You should change this to list(buf,indentlevel+1) because you are only going up one level. This way you can keep track of directory levels. Add another function to add extra spaces. See the example below:

void space(int level, int file)
{
    int i;
    for (i = 0; i < level + 1; i++)
        printf("\x0b3   "); // add the '│' character
    if (file) 
        printf("\x0c3\x0c4  "); // add  '├' and '─' characters
}

void list(const char *path, int indentlevel)
{
    DIR *dirp = opendir(path);
    struct dirent *dentry;
    char buf[1024];
    if (!dirp)
    {
        printf("%*sNo access\n",indentlevel,"");
        return;
    }

    int i;
    while ((dentry = readdir(dirp)) != NULL)
    {
        sprintf(buf,"%s/%s", path, dentry->d_name);
        switch (testDir(buf,dentry->d_name))
        {
        case doSkip:
            break;
        case isDir:
            space(indentlevel, 1);
            putchar('\n');
            space(indentlevel, 0);
            printf("[ %s ]\n",dentry->d_name);
            list(buf,indentlevel+1);
            break;

        case isFile:
            space(indentlevel-1, 1);
            printf("%s\n",dentry->d_name);
            break;
        }
    }

    closedir(dirp);
}