printing - C: how to print out tree_node data? -
i building traversable directory tree.
this diagram drew understand structure easily: how print out list of subdirectories (subdir) of current working directory (cwd)?
so example, use shell commands in order:
mk_directoryname, cd_directoryname, ls
below code attempt, seems print directories , not subdirectories of cwd:
// prints children of directory cwd (not recursively) void do_ls(struct tree_node *cwd) { printf("listing directories...\n"); struct list_node *subdir = cwd -> first_child; while (subdir != null) { printf("%s\n", subdir ->tree -> string_buffer); subdir = subdir->next; } } // *checks whether cwd has subdirectory named arg // *if yes, function returns corresponding tree node (and become new working directory) // *if no, prints error message // *handle cd , cd .. struct tree_node *do_cd(struct tree_node *cwd, struct tree_node *root, char *arg) { // checks if cwd has subdirectory named arg struct list_node *subdir = cwd -> first_child; while (subdir != null) { if (strcmp(subdir->tree->string_buffer, arg) == 0) { printf("subdirectory exists: entering!\n"); cwd = subdir->tree; printf("making subdirectory current working directory: name = %s\n", arg); printf("returning current working directory: %s.\n", arg); return cwd; } subdir = subdir->next; } printf("directory not exist!\n"); return cwd; }
rest of code:
#include <stdio.h> /* fgets(), fprintf() , printf() */ #include <stdlib.h> /* exit_failure */ #include <ctype.h> /* isspace() */ #include <string.h> #include <stddef.h> // commands char exitprogram[] = "exit"; char listdirectory[] = "ls"; char commanddirectory[] = "cd"; char makedirectory[] = "mkdir"; char removedirectory[] = "rmdir"; // holds string buffer of length 128 // pointer parent // pointer first node of list of children typedef struct tree_node { char string_buffer[128]; struct tree_node *parent; struct list_node *first_child; // first node of list of children? } tree_node; // pointer tree node // pointer next item in list typedef struct list_node { struct tree_node *tree; struct list_node *next; } list_node; // allocates right amount of space tree node // sets pointers null // initialises string buffer given name // returns pointer tree node struct tree_node *make_tree_node(char *name) { tree_node *tree = malloc(sizeof(*tree)); tree -> parent = null; tree -> first_child = null; strcpy(tree -> string_buffer, name); return tree; } // allocates new list node // assigns fields tree node references , next list node // returns pointer new list node struct list_node *make_list_node(struct tree_node *v, struct list_node *next) { list_node *instance = malloc(sizeof(*instance)); instance -> tree = v; instance -> next = next; return instance; } // checks whether directory named arg exists in current working directory // creates directory if not exist // if arg null, function should print error message void do_mkdir(struct tree_node *cwd, char *arg) { //printf("making directory name %s\n", arg); // check if directory exists struct list_node *subdir = cwd->first_child; while (subdir != null) { if (strcmp(subdir->tree->string_buffer, arg) == 0) { printf("directory name exists. please provide name.\n"); return; } subdir = subdir->next; } // adding new directory struct tree_node *newsubdir = make_tree_node(arg); newsubdir->parent = cwd; struct list_node *newlistnode = make_list_node(newsubdir, null); // putting new node in alphabetical order struct list_node *prev = null; if (subdir == null) { newlistnode->next = cwd->first_child; cwd->first_child = newlistnode; } else { while (subdir != null) { // todo: use case insensitive compare if (strcmp(arg, subdir->tree->string_buffer) > 0) { // inserting in front newlistnode->next = subdir->next; prev->next = newlistnode; break; } prev = subdir; subdir = subdir->next; } if (subdir == null) { subdir->next = newlistnode; } } printf("directory added: %s\n", arg); } // prints children of directory cwd (not recursively) void do_ls(struct tree_node *cwd) { printf("listing directories...\n"); struct list_node *subdir = cwd -> first_child; while (subdir != null) { printf("%s\n", subdir ->tree -> string_buffer); subdir = subdir->next; } } // *checks whether cwd has subdirectory named arg // *if yes, function returns corresponding tree node (and become new working directory) // *if no, prints error message // *handle cd , cd .. struct tree_node *do_cd(struct tree_node *cwd, struct tree_node *root, char *arg) { // checks if cwd has subdirectory named arg struct list_node *subdir = cwd -> first_child; while (subdir != null) { if (strcmp(subdir->tree->string_buffer, arg) == 0) { printf("subdirectory exists: entering!\n"); cwd = subdir->tree; printf("making subdirectory current working directory: name = %s\n", arg); printf("returning current working directory: %s.\n", arg); return cwd; } subdir = subdir->next; } printf("directory not exist!\n"); return cwd; } struct tree_node *do_cd_root(struct tree_node *cwd, struct tree_node *root) { printf("returning root directory.\n"); return root; } struct tree_node *do_cd_parent(struct tree_node *cwd) { // initialising parent directory tree_node struct tree_node *pardir = cwd -> parent; printf("making current working directory parent directory.\n"); cwd = pardir; printf("returning parent directory.\n"); return cwd; } // *prints prompt (e.g. /bar/baz/ >) in every iteration of main loop // *show directories on path in correct order //void show_prompt(struct tree_node *cwd) { // while(cwd != null) { // printf(cwd->string_buffer); //show directories on path in correct order. // } // printf("/"); //} // *removes node child parent node dir // *take care correctly support corner cases child being 1 // *all memory occupied child should freed //void remove_child(struct tree_node *dir, struct tree_node *child) { // if (dir == null) { // printf("current directory empty!"); // } // else if (dir -> child != null) { // free(child); // } //} // implement rmdir (follow same pattern previous exercise) // *if specified directory not empty, rmdir should fail error message //void do_rmdir(struct tree_node *cwd, char *arg) { // if(cwd != null) { // printf("specified directory not empty!"); // } else { // free(cwd); // } //} int main(void) { char directoryname[129] = ""; printf("\nprogram start... \n\n"); // getting user input string // , splitting command , argument char inputstring[129]; char delimiter[] = " "; char *line; char *arg; struct tree_node *root = make_tree_node("root\0"); //struct tree_node *cwd = make_tree_node("root\0"); struct tree_node *cwd = root; printf("/%s >", directoryname); while (fgets(inputstring, 128, stdin)) { inputstring[strlen(inputstring) - 1] = '\0'; // char * before strsep, set pointer original checkstring // original checkstring // free memory // gets argument , stores arg line = malloc(strlen(inputstring) + 1); strcpy(line, inputstring); arg = strsep(&line, delimiter); arg = strsep(&line, delimiter); printf("your argument: %s\n", arg); //printf("userinput:%s", inputstring); if(strncmp(inputstring, "exit", 4) == 0) { printf("breaking...\n"); break; } ////////////////////////////// handling ls //////////////////////////// else if(strncmp(inputstring, "ls ", 3) == 0) { printf("the ls command should used without arguments.\n"); } else if(strncmp(inputstring, "ls", 2) == 0) { do_ls(cwd); printf("/%s >", directoryname); } ////////////////////////////// handing cd ///////////////////////////// else if(strncmp(inputstring, "cd ..", 5) == 0) { do_cd_parent(cwd); printf("/%s >", directoryname); } else if(strncmp(inputstring, "cd .", 4) == 0) { printf("returning current directory.\n"); printf("/%s >", directoryname); } else if(strncmp(inputstring, "cd ", 3) == 0) { do_cd(cwd, root, arg); printf("/%s >", directoryname); } else if(strncmp(inputstring, "cd", 2) == 0) { do_cd_root(cwd, root); printf("/%s >", directoryname); } /////////////////////////// handling mkdir ///////////////////////////// else if(strncmp(inputstring, "mkdir ", 7) == 0) { printf("please specify directory name not null: mkdir directoryname\n"); printf("/%s >", directoryname); } else if(strncmp(inputstring, "mkdir ", 6) == 0) { do_mkdir(cwd, arg); printf("/%s >", directoryname); } else if(strncmp(inputstring, "mkdir", 5) == 0) { printf("please specify directory name: mkdir directoryname\n"); printf("/%s >", directoryname); } //////////////////////// handling rmdir ///////////////////////////////// else if(strncmp(inputstring, "rmdir ", 7) == 0) { printf("please specify directory name not null: rmdir directoryname\n"); printf("/%s >", directoryname); } else if(strncmp(inputstring, "rmdir ", 6) == 0) { printf("removing directory name...\n"); // printf("/%s >", directoryname); } else if(strncmp(inputstring, "rmdir", 5) == 0) { printf("please specify directory name: rmdir directoryname\n"); printf("/%s >", directoryname); } else { printf("unrecognised input: please try again.\n"); printf("/%s >", directoryname); } } printf("\nprogram quit... \n\n"); // free memory return 0; }
this can done using using depth first search , can explode paths current root of tree (means current selected directory).
Comments
Post a Comment