My tree command for POSIX systems in C

I like the tree command. It’s nice to have when working with lots of directories and it brings an ‘graphic’ element to the command line 🙂 I’m here going to show a simple tree solution in C that I usually use as a base for more complicated implementations.

#include <string>
#include <dirent.h>
 
void rec_walker(const char *path, int level);
char* writer(int level);
 
int main(int argc, char const *argv[]) {
 
	DIR        *dir;
	const char *path;
 
	path = argv[1];
 
	// If no path set current path
	if (path == NULL) {
		path = ".";
	}
 
	// Test if dir  	
  	dir = opendir(path);
 
  	if(dir) {  		
    	    rec_walker(path, 0);
  	}
  	else {
  		printf("%s is not a directory\n", argv[1]);
  		return 1;
  	}
 
	return 0;
}

Im here using the standard library for common string operations and the dirent.h for easy access to the filesystem. First we have to define our external (not in main()) functions, rec_walker() and the writer() function (more about these later).
Then we set the path that we want to traverse. If no path from argv[] we set current directory as path. Now that we have a path we test to see if it is a directory and if it is we call the rec_walker() function:

void rec_walker(const char *path, int level){
	struct dirent *file;
	DIR *directory;
 
	chdir(path);
 
	directory = opendir(".");
 
	if(directory){
		while ((file = readdir(directory)) != NULL) {
 
			if (strcmp( file->d_name, "." ) != 0 && strcmp( file->d_name, ".." ) != 0) {			
 
				if (file->d_type == DT_DIR) {
					printf("%s%s:\n", writer(level + 1), file->d_name);
					rec_walker(file->d_name, level + 1);
				}
				else{
	      			printf("%s%s\n", writer(level), file->d_name);
	      		}
	      	}	
    	}
    	closedir(directory);
    }	
 
}

The rec_walker() function takes the path (as string) and a level (as int). The level variable is uses for a little ‘pretty print’. The rec_walker() function lists all files in the directory, and if the ‘file’ is a directory (DT_DIR) it will recursively call itself with the new path and an incremented level. It continues to do this until no directories are left.

Now we add a little ‘pretty print’ with the writer() function:

char* writer(int level){
 
	const char characters[] = "-----------------------------------";
	char result[] = "";
 
	// Max levels 
	if (level > 18)	{
		level = 18;
	}
 
	return strncat(result, characters, level * 2);
 
}

This function simply returns some lines to ‘indent’ the different levels to make it easier to read (very simple)

Example output from the above code:

--test:
--test_file.txt
----test_lvl2:
----test_file_lvl2.txt
treeplus
treeplus.c

Tested on gcc 4.2.1 and OSX 10.7.5

Comments are closed.

Niklas Tech Blog
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.