文件树链表创建

 

基于 基于树结构自己的操作系统文件系统构建,使用C语言实现 - 知乎 (zhihu.com)

进行二次开发,补充部分代码,后续在

Windows控制台cmd -tree 命令功能的实现——知乎别人的代码搬运实测情况——基于树结构自己的操作系统文件系统构建,使用C语言实现_哔哩哔哩_bilibili

进行一些更新

不多说上代码,Devc++复制粘贴就能跑

命令

ct是显示文件树

c_d是创建文件夹,但是目前只能创建链表索引,实际上没有创建真的文件夹,

c_f是创建文件,同样只能创建索引。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>


//解决文件加入a->child,实现子文件
//解决文件打印竖线 0开始,%5=1打印,5倒数 +=5


//typedef struct paper{
//	char name[50];
//	int isfile;
//	paper* next;
//}paper;
//
//
//typedef struct dictionary{
//	char name[50];
//	int isfile;
	node* parent;
//	dictionary* child;
//	paper* pa;
//};


//由于一个节点下面,既要有文件,也要有文件夹,所以file->child既要能指向文件类型,也要指向文件夹类型。所以只能是这里同一个节点类型,因为兼容类型还不会写。
//同一个节点类型,但是区分不同使用,要在节点里加上标志位flag ——is_dictionary

typedef struct node {
	char name[100];
	int is_dictionary;
	node* child;
	node* parent;
	node* bro;
} node;
node *root;
void init() {
	root = (node*)malloc(sizeof(node));
	strcpy(root->name, "root");
	root->parent = NULL;
	root->child = NULL;
	root->bro = NULL;
	root->is_dictionary = 1;
}
void addbro(node* parent, node* a) {
	if (parent->bro == NULL) {
		parent->bro = a;
	} else {
		node* bro = parent->bro;
		while (bro->bro != NULL) {
			bro = bro->bro;
		}
		bro->bro = a;
	}
}
//void addChild(node* parent, node* a)
//跳转前的内存位置,取得改内存里跳转后的新内存地址
//void addChild(node* &parent, node* a)
//不进行跳转获取原位置,因为节点永远存在不为空
void addChild(node* parent, node* a) {
	if (parent->child == NULL) {
		parent->child = a;
	} else {
		node* bro = parent->child;
		while (bro->bro != NULL) {
			bro = bro->bro;
		}
//		bro->bro = NULL;
		bro->bro = a;
	}
}
void addFile(node* parent, char a[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
	addbro(parent, p);
}
void addDictionary(node* parent, char a[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 1;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//		addbro(parent, p);
	addChild(parent, p);
	printf("success creat dictionary\n");
}

//先就着基本有的直接敲上,然后打印递归的时候发现传进指针,一开始的root变量就要改成指针
void show(node* list, int floor, int head) {
	node *a = list;
	int tab = floor;
//	printf("%d\n", floor);
	while (a != NULL) {
		for (int i = 0; i < head + 20; i++) {
			printf("^");
		}
		floor = tab;
//		去除一开始的缩进,由之前的addbro改成addchild,文件夹的child不为NULL,->child才能进入,这样才能打开文件夹
		while (floor > 0) {
//			printf("%d\n", floor);
//			printf("|");
			if (floor % 5 == 1) {
//				从0开始,倒数到1
				printf("|");
//				每下一层就是floor+5,对应一个竖,
			} else {
				printf(" ");
			}
			floor--;
		}
		if (a->is_dictionary) {
			printf("-%-18s  %-3s\n", a->name, "dictonary");
//			左对齐缩进
			show(a->child, tab + 5, head);
		} else {
			printf("-%-7s  %-s\n", a->name, "<file>");
		}
		a = a->bro;
	}
}

//输出,查找,标记,替换,增加  族


//文件夹读取
//文件所有子项目读取
//文件写入.txt
//配合链表,实现代码命令创建
//选择文件传输
//在结合服务器实现云创建文件传送

//原版查找增加,现用于增加文件

void findandadd(node* list, int floor, char name[], char have[]) {
	node *a = list;
//	int tab = floor;
	while (a != NULL) {
//		floor = tab;
//		while (floor) {
//			printf(" ");
//			floor--;
//		}
		if (a->is_dictionary) {
//			printf("-%s\n", a->name);

			if (strcmp(a->name, name) == 0) {
				printf("FIND name\n");
				addFile(a, have);
				return ;
			}
			findandadd(a->child, 0, name, have);
//		show(a->child, floor + 1);
		} else {
//			printf("|-%s\n", a->name);
			if (strcmp(a->name, name) == 0) {
				printf("FIND name\n");
				addFile(a, have);
				return ;
			}
		}
		a = a->bro;
	}
//	printf("find error\n");
//需要控制只要查到,递归就不再做其他运算,直接退出,加结构体
}



//优化版本-增加文件夹
void findadd_dir(node* list, int floor, char name[], char have[]) {
	node *a = list;
//	int tab = floor;
//	while (a != NULL) {
//		floor = tab;
//		while (floor) {
//			printf(" ");
//			floor--;
//		}
	if (a->is_dictionary) {
//			printf("-%s\n", a->name);
		if (strcmp(a->name, name) == 0) {
			printf("FIND name\n");
			addDictionary(a, have);
			return ;
		}
		findadd_dir(a->child, 0, name, have);
//		findadd_dir(a->bro, 0, name, have);
//		show(a->child, floor + 1);
	} else {
//			printf("|-%s\n", a->name);
		if (strcmp(a->name, name) == 0) {
			printf("FIND name\n");
			addDictionary(a, have);
			return ;
		}
	}
	a = a->bro;
}



int main() {
	init();
	char a[100] = "n";
	char b[100] = "nwoevi";

	addDictionary(root, a);
	printf("dictionary ok!\n");
	addFile(root, b);
	printf("File b ok!\n");
	char c[100] = "3894";
	addFile(root, c);
	printf("File 3849 ok!\n");


	char d[100] = "floor2";
//	findandadd(root, 0, a, d);
	addDictionary(root, d);



	char k[100]="vnsn";
	findadd_dir(root,0,a,k);
	char f[100]="ij";
	findandadd(root,0,k,f);


	char ch[100] = {};
//	show(root, 0, 10);
//0导致一开始就先打印|,得最后打印|倒数到1
//	5不行,从4开始
//	show(root, 4, 10);
	show(root, 0, 10);
	printf("input order\n");


	while (1) {
//		gets(ch);
		scanf("%s", ch);
		if (strcmp("close", ch) == 0) {
			break;
		} else if (strcmp("c_f", ch) == 0) {
			printf("Input file name:\n");
//			gets(ch);
//			gets()会把函数printf()打印出的回车吸收掉,所以用scanf,不受缓冲区影响
			scanf("%s", ch);
			printf("Input parent contest name:\n");
			char tar[100];
//			gets(tar);
			scanf("%s", tar);
			findandadd(root, 0, tar, ch);
			printf("success creat file\n");
		} else if (strcmp("c_d", ch) == 0) {
			printf("Input dictionary name:\n");
			scanf("%s", ch);
			char tar[100];
			printf("Input parent contest name:\n");
//			gets(tar);
			scanf("%s", tar);
			findadd_dir(root, 0, tar, ch);
//			findadd_dir(root,0,"n",ch);
//			printf("success creat dictionary\n");        内置在子函数里了,解决查找失败仍提示创建成功问题 
		} else if (strcmp("st", ch) == 0) {
			show(root, 0, 10);
//			无缩进
//			show(root, 5, 10);
//			缩进前有|
//			show(root, 4, 10);
//			show(root, -1, 10);
			printf("\ntree end\n");
		} else {
			printf("commond not found\n");
			continue;
		}


	}


	findandadd(root, 0, "n", "newnode");
	show(root, 0, 30);
	return 0;
}

  • 20
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值