DevC++ C文件树 实现 用户文件前缀的自定义

 文件树新增功能:实现创建自定义前缀的文件,原始材料详见

DevC++文件树-windows下链表标记与标记节点的隐藏、重现-CSDN博客

 新功能:

用户名与密码匹配,默认合法用户名是0到99,密码和用户名相同

用户自定义文件前缀。

如图

DevC++ C文件树 实现 用户文件前缀的自定义_第1张图片
 
和之前版本的文件,代码不同,全局变量root节点变成局部变量,大部分的函数的参数都多了一个空间名字。创建多个不同的文件。实现不共用。

真正的应用在于给服务器的每个客户端分配一些文件路径,使得各个用户看到的文件名,但是服务器能够通过前缀修改的路径进行区分不同用户的同名文件。

demo的改写,基于全局变量和先前的常量“mysecret_”的位置,进行替换。常量"mysecret_",和全局变量root 实现了会啥写啥。以此无中生有,产生了前缀,制造了文件路径。又通过前缀加入练手,对根节点无中生有前缀,实现文件不会被共用,因为路径不同,前缀不同。

现在就着改写第一版本的文件树,发现常量替换变量,最难的位置选择其实早就在常量随便设置上解决了,常量延续使用,随着代码增多,但是常量的位置不变,常量又可以看成某个函数返回一个固定值,这样就确定了常量直接替换成变量,是可靠的。如此马后炮似的解答如何选择变量的设置位置。

变量引入,就相当于引入一个控制常量变化的联系,通过嵌套函数的参数增加,发现嵌套函数在变量串起来后,有了更直观的理解——多个嵌套函数共用一个参数,正是因为被嵌套的函数增加了控制变量,其他嵌套的函数就依次增加控制变量。就能实现全局变量变局部变量,实现功能封装,保证没有变量在main函数之外,main里面的函数就能整体直接复制粘贴到服务端的线程当中。

代码有两个版本,一个是就着旧代码尽量只增不减的 带修改遗迹的完整代码,可以一行一行和DevC++文件树-windows下链表标记与标记节点的隐藏、重现-CSDN博客进行比较

另一个是删除精简之后的代码版本,在文案的最后即可见到。有一段半个A4大小的空白,比较容易找到。

这个是只增不减版本的代码,可用于追溯当时细节。也可用于记录,证明自己确实可以就着一堆代码慢慢改。

这个版本的代码和DevC++文件树-windows下链表标记与标记节点的隐藏、重现-CSDN博客

 对比可以知道具体是怎么来的,中间的改bug过程,

穷举出来的代码遗迹的看法:

1.位置:新旧函数里的距离比较近,可以了解动手敲代码的开辟就是复制粘贴,然后注释函数,在粘贴旧的思路,实现函数替换。

2.个数:有很多的printf插入其中,一般都是写完了发现功能跑不动,没有输出,就看到底是哪一步运行停止了,数据哪一块没有赋值成功。

3.功能含义:对比函数内部的注释,可以知道具体函数的谱系,比如名称里带add函数的,里面都会有相同的绿色的注释痕迹,而且注释的代码相同的,就是关系进的,注释代码多的,就是代码进化多的,

4.代码设计思路:可以通过对比相同族的函数里面的注释块,可以知道是先有思路,然后再改代码。但是表现出来,却是代码重新命名,最初文件树残留的代码注释隔了好几个博客在这里重新出现,如字符串前缀粘贴。从残留的代码和各版本陆续遗留的代码对比,可以知道代码改写到显而易见需要经过两三步的换名,一次替换10%,两次之后能够主动意识到新的思路。

#include
#include
#include
#include 
//解决13.里面的删除标记失败以及新增显示已删除的文件夹文件
//child->child->bro解决多个同级文件夹插入file文件,不能确认母节点问题
//解决文件加入a->child,实现子文件
//lenth-tab,解决文件打印竖线 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

int lenth = 20;
//文件类型后缀统一

typedef struct node {
//	文件树节点结构体
	char name[100];
//	节点名称,和路径不同,路径自动加入前缀,藏进了path里,printf 出来 可了解成员存储的内容
	char path[100];
//	10.版本出现文件创建,需要相对路径 ,path存储到上一级文件名+./,因为再加当前文件名,同级文件就会塞进下一个文件里
	int is_dictionary;
//	标志1:节点是文件夹:1,否则=0
	int is_dead = 0;
//	标志2:节点是标记删除的节点:1否则=0
	node* child;
	node* parent;
	node* bro;
} node;
node *root;

typedef struct user {
	char acount[100];
	char code[100];
} user;
//这是改secret_前缀的测试思路,成功穷举出矛盾。这个函数属于零起点,遇到矛盾,自然而然的理解,主要是找到这个并记录自然而然
//这个函数解决了如何判断前缀./的封装程度
void addprofix(char a[]) {

	char *b = "./mysecret_root./";
//		根节点加前缀
//		非根节点加后缀
//		只输入文件名,其他对外隐藏
	char *c = "./";
//		addbro ,在本层文件里,加在前缀
//		如 n->./mysecret_root./n
//			p->./mysecret_root./p


//		addchild,在下层文件里, 加后缀上
//			p->./mysecret_root./->./mysecret_root./n./p
//		后缀的./也一起存进去。名称之前,封装为路径,孩子之后,复制自己名称,在加入./作为路径。

//		addchild,在下层文件里, 上级文件名的加后缀上./
//			p->./mysecret_root./->./mysecret_root./n./ p


//	每个节点存上一个路径,不存自己的名字,
//	添加兄弟就直接复制粘贴,
//	添加孩子就再补充自己的名字,然后进入下一条。自然而然。

	//	默认创建在本地同文件里的mysecret_root文件里
	//	且直接输入名字即可创建
//		char a[100];
//		scanf("%s", a);
	char m[100] = {0};
	strcat(m, b);
	strcat(m, a);
	printf("%s\n", m);
}

int fun(char*filepath) {
	int res;
	//filepath为绝对路径
	//如果文件夹不存在
	if (_access(filepath, 0) != 0)
		//创建文件夹
		res = mkdir(filepath);// 返回 0 表示创建成功,-1 表示失败
	//remove(filename) 删除文件
	else
		res = 1;
	return res;
}
//map字母数字负责映射,或者符号数字负责映射
//然后switch case来直接跳转判断速度

//移植自0.自定义根目录前缀
void init() {
	root = (node*)malloc(sizeof(node));
	strcpy(root->path, "./mysecret_root");
	strcpy(root->name, "root");
	root->is_dead = 0;
	root->parent = NULL;
	root->child = NULL;
	root->bro = NULL;
	root->is_dictionary = 1;
//	int flag = fun("./mysecret_root");
//	int	flag = fun(root->path);
//	if (flag == -1)
//		printf("创建失败\n");
//	else if (flag == 0)
//		printf("创建成功\n");
//	else if (flag == 1)
//		printf("文件夹已存在\n");
	int	flag = fun(root->path);
	if (flag == -1)
		printf("磁盘根文件创建失败\n");
	else if (flag == 0)
		printf("磁盘根文件创建成功\n");
	else if (flag == 1)
		printf("磁盘根文件夹已存在\n");
}


void initv2(node* rootv2, char privaterootname[]) {
//	rootv2 = (node*)malloc(sizeof(node)); 如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
//	strcpy(root->path, "./mysecret_root");
	char *a = "./";
	char path[100] = {""};
	strcat(path, a);
	strcat(path, privaterootname);
	strcat(path, "_root");   //这是改出来的代码新增的一行/
	strcpy(rootv2->path, path);
	strcpy(rootv2->name, "root");
	rootv2->is_dead = 0;
	rootv2->parent = NULL;
	rootv2->child = NULL;
	rootv2->bro = NULL;
	rootv2->is_dictionary = 1;
	printf("%s\n", rootv2->path);
//	int flag = fun("./mysecret_root");
//	int	flag = fun(root->path);
//	if (flag == -1)
//		printf("创建失败\n");
//	else if (flag == 0)
//		printf("创建成功\n");
//	else if (flag == 1)
//		printf("文件夹已存在\n");
	int	flag = fun(rootv2->path);
	if (flag == -1)
		printf("磁盘根文件创建失败\n");
	else if (flag == 0)
		printf("磁盘根文件创建成功\n");
	else if (flag == 1)
		printf("磁盘根文件夹已存在\n");
}

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) {
	strcpy(a->path, parent->path);
//	人脑跑代码,跑到第二次发现,名字后面缺了./
//	意识到如果./在根文件开始,就会一直有这个二次文件沿用一次文件,复制粘贴一次,缺少下级./情况
//	于是按照二次文件改,看看这样在根文件创建的时候能不能适配
//	发现新创建的文件可以直接加上下级指令,根文件最后是名字,然后下次创建子文件,在子文件上在加上./
	strcat(a->path, "./");  //下层指令
	strcat(a->path, "mysecret_");
	strcat(a->path, a->name);

//	下面三次循环可以看成从根节点开始,连续三次创建文件,三层文件名都间隔了一个./符合路径格式,一切正常
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
	if (a->is_dictionary) {
		fun(a->path);
	} else {
		strcat(a->path, ".txt");
		FILE* fp;
		fp = fopen(a->path, "w");
		fclose(fp);
	}

	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 addChildv2(node* parent, node* a, char privaterootname[]) {
//	printf("addChild path is a%s\n",a->path);		//debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
//	printf("parent path is %s",parent->path);  		 //debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	strcpy(a->path, parent->path);   //path是上级文件,所以下面需要./继续深入
//	人脑跑代码,跑到第二次发现,名字后面缺了./
//	意识到如果./在根文件开始,就会一直有这个二次文件沿用一次文件,复制粘贴一次,缺少下级./情况
//	于是按照二次文件改,看看这样在根文件创建的时候能不能适配
//	发现新创建的文件可以直接加上下级指令,根文件最后是名字,然后下次创建子文件,在子文件上在加上./

	strcat(a->path, "./");  //下层指令,此时才算进入下层
	strcat(a->path, privaterootname);
	strcat(a->path, "_");
//	strcat(a->path, "mysecret_");      替换固定头文件。 其他不思考。 回头再按之前的mysecret_实现的思路重复一遍,加前缀后重复一遍,留前缀去后缀替换后再重复一遍。
	strcat(a->path, a->name);

//古早注释在新的需求下有了新的含义,复用穷举法
//	下面三次循环可以看成从根节点开始,连续三次创建文件,三层文件名都间隔了一个./符合路径格式,一切正常
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//	printf("check add head now a is %s\n", a->path);		//debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	if (a->is_dictionary) {

		fun(a->path);
	} else {
		strcat(a->path, ".txt");
		FILE* fp;
		fp = fopen(a->path, "w");
		fclose(fp);
	}

	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->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//	addbro(parent, p);
//	printf("add function is running\n");

	addChild(parent, p);
//	printf("success creat file\n");
}

void addDictionary(node* parent, char a[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 1;
	p->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//		addbro(parent, p);
//	printf("add function is running\n");
	addChild(parent, p);
//	printf("success creat dictionary\n");
}
//缩进输出文件类型名,只能减少,不能增加,增加就会都增加,减少可以选择性减少
//增加就会先算出最深的,然后算出距离差,然后再加上,不如一遍算缩进,还剩下多少,直接打印没有被占用的
//void format(node *a, int tab, int see) {
//	printf("%-18s", a->name);
//	for (int i = 0; i < see - tab; i++) {
//		printf(" ");
//	}
//	printf("%-9s", "dictionary");
//
//}


void addFilev2(node* parent, char a[], char privaterootname[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 0;
	p->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//	addbro(parent, p);
//	printf("add function is running\n");

	addChildv2(parent, p, privaterootname);     //重写的另一种情况:从注释一行代码到 复制粘贴代码块,代码块里面的函数直接加新的参数。
//	核心函数增加参数 ,其他嵌套函数增加相同参数,可以借此形成线索,这个新思想的背景,则是来源于相同代码的复制粘贴,修改参数。
// 从改一个函数一个参数到改两个函数一个参数
//从改两个函数一个参数到改两个嵌套函数一个参数
//再到新增功能,新增自定义功能时,各个函数新增相同参数作为控制
//再到模块移植,从一个功能实现到模块化,就是把原来的主函数变成某个小函数,原来主函数需要的变量,全部放进小函数里。
//这就是新功能实现的无中生有的流程,纯纯一个一个函数加参数 ,改的多了,规模大了,遇着的函数与函数之间的联系,自然而然描述出来修改思路。

//	printf("success creat file\n");
}


void addDictionaryv2(node* parent, char a[], char privaterootname[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 1;
	p->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//		addbro(parent, p);
//	printf("add function is running\n");       //debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	addChildv2(parent, p, privaterootname);
//	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", a->name);
			for (int i = 0; i < lenth - tab; i++) {
				printf(" ");
			}
			printf("%-9s\n", "dictionary");
//			printf("-%-18s  %-3s\n", a->name, "dictonary");
//			左对齐缩进
			show(a->child, tab + 5, head);
		} else {
//			format(a->name,tab,lenth);

			printf("%-18s", a->name);
//			左对齐18长度,lenth=20被挤出,lenth=30不会超出
			for (int i = 0; i < lenth - tab; i++) {
				printf(" ");
			}
//				printf("%-5d", tab);
			printf("%-9s\n", "");
//			printf("-%-7s  %-s\n", a->name, "");
		}
		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 {
			if (strcmp(a->name, name) == 0) {
				printf("FIND name\n");
				addFile(a, have);
				return ;
			}
		}
		a = a->bro;
	}
//需要控制只要查到,递归就不再做其他运算,直接退出,加结构体
}


//优化版本-增加文件夹
void findadd_dir(node* list, int floor, char name[], char have[]) {
	node *a = list;

	while (a != NULL) {
		if (a->is_dictionary) {
			printf("-checking dictionary-%s\n", a->name);
			if (strcmp(a->name, name) == 0) {
				printf("FIND name %s\n", a->name);
				addDictionary(a, have);
				return ;
			}

			findadd_dir(a->child, 0, name, have);

		} else {

		}
		a = a->bro;
	}
}


void findandaddv2(node* list, int floor, char name[], char have[], char privaterootname[]) {
	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");
				addFilev2(a, have, privaterootname);
				return ;
			}
			findandaddv2(a->child, 0, name, have, privaterootname);
//		show(a->child, floor + 1);
		} else {
			if (strcmp(a->name, name) == 0) {
				printf("FIND name\n");
				addFilev2(a, have, privaterootname);
				return ;
			}
		}
		a = a->bro;
	}
//需要控制只要查到,递归就不再做其他运算,直接退出,加结构体
}


//优化版本-增加文件夹
void findadd_dirv2(node* list, int floor, char name[], char have[], char privaterootname[]) {
	node *a = list;

	while (a != NULL) {
		if (a->is_dictionary) {
//			printf("-checking dictionary-%s\n", a->name);
			if (strcmp(a->name, name) == 0) {
				printf("FIND name %s\n", a->name);
				addDictionaryv2(a, have, privaterootname);
				return ;
			}

			findadd_dirv2(a->child, 0, name, have, privaterootname);

		} else {

		}
		a = a->bro;
	}
}



//void changename(node* list, char have[]) {
	node *a = list;
	node *prior;
	node *dead = a;
	char newname[100];
	char *deadsign = "dead_";
	strcat(newname, deadsign) ;
	strcat(newname, dead->name);
	rename(dead->name, newname);
//
//	node *a = list;
//	rename(a->name, have);
//}

//void deadsignshow(node* list) {
//	node *a = list;
//	node *dead = a;
//	char newname[100];
//	char *deadsign = "dead_";
//	strcat(newname, deadsign) ;
//	strcat(newname, dead->name);
//	rename(dead->name, newname);
//}

void deadaddsign_v2(node* list) {
//	node* a=list->child
//	node* a=list;
	node* a = list->child;
	while (a != NULL) {
		if (a->is_dictionary) {
			a->is_dead = 1;
//				deadsignv2(a);
//			deadaddsign_v2(a->child);
			deadaddsign_v2(a);
		} else {
			a->is_dead = 1;
		}
		a = a->bro;
//		因为传入本级bro,所以要a=list->child,不然list-bro就会一块标记
	}
}

//
//void deadChild(node* list) {
//	node *a = list;
//	node *prior;
//	node *dead;
//	//	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 ;
			}
//			deadChild(a->child);
//			//		show(a->child, floor + 1);
//		} else {
//			while (a != NULL) {
//				prior = a;
//				if (a->bro->is_dictionary == 1) {
//
					if(a->bro->child==NULL){
						dead=a->bro;
						a->bro=dead->bro;
						free(a);
					}
//				} else {
//					dead = a->bro;
//					char *deadsign = "dead_";
//					char newname[100];
//
//					strcat(newname, deadsign) ;
//					strcat(newname, dead->name);
//					rename(dead->name, newname);
					remove(dead->path);
//
//				}
//
//			}
//		}
//		prior = a;
//		a = a->bro;
//	}
//}


void findanddead(node* list, char have[]) {
	node *a = list->child;
	//	int tab = floor;
	while (a != NULL) {
		if (a->is_dictionary) {
			if (strcmp(a->name, have) == 0) {
				printf("FIND name\n");
				addFile(a, have);
				a->is_dead = 1;
				deadsignv2(a->child);
				a->is_dead = 1;
				deadaddsign_v2(a);
				v2到_v2,封装当前目录先标记,然后再进入child进行修改
				return ;
			} else {
				if (a->child != NULL) {
					findanddead(a->child, have);
				}
			}
			//		show(a->child, floor + 1);
		} else {
			if (strcmp(a->name, have) == 0) {
				printf("FIND name\n");
//				addFile(a, have);
				a->is_dead = 1;
				return ;
			}
		}
		a = a->bro;
	}
}

//复制粘贴自show()函数,隐藏删除文件
void showhidedead(node* list, int floor, int head) {
//	node *a = list->child;
	node *a = list;
	int tab = floor;
	while (a != NULL) {
		if (a->is_dead) {
			a = a->bro;
			continue;
		} else {
			for (int i = 0; i < head + 20; i++) {
				printf("^");
			}
			floor = tab;
			while (floor > 0) {
				if (floor % 5 == 1) {
					printf("|");
				} else {
					printf(" ");
				}
				floor--;
			}
			if (a->is_dictionary) {
				printf("%-18s", a->name);
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "dictionary");
				if (a->child != NULL) {
					showhidedead(a->child, tab + 5, head);
				}
			} else {
				printf("%-18s", a->name);
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "");
			}
			a = a->bro;
		}
	}
}

//显示删除文件,并且打印标记已经删除的文件前缀
void showwithdead(node* list, int floor, int head) {
	node *a = list;
	int tab = floor;
	while (a != NULL) {
//		if (a->is_dead) {
//			a = a->bro;
//			deadsignshow(a);
//			continue;
//		} else
		{
			for (int i = 0; i < head + 20; i++) {
				printf("^");
			}
			floor = tab;
			while (floor > 0) {
				if (floor % 5 == 1) {
					printf("|");
				} else {
					printf(" ");
				}
				floor--;
			}
			if (a->is_dictionary) {
				if (a->is_dead) {
					char newname[100];
					char *deadsign = "dead_";
					strcat(newname, deadsign) ;
					strcat(newname, a->name);

					printf("%-18s", newname);
					//				printf("%-18s", a->name);
				} else {
					printf("%-18s", a->name);
				}
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "dictionary");
				showwithdead(a->child, tab + 5, head);
			} else {
				if (a->is_dead) {
					char newname[100];
					char *deadsign = "dead_";
					strcat(newname, deadsign) ;
					strcat(newname, a->name);

					printf("%-18s", newname);
					//				printf("%-18s", a->name);
				} else {
					printf("%-18s", a->name);
				}
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "");
			}
			a = a->bro;
		}
	}
}


void checklogin(char a[], char b[]) {

	FILE* fp;
	fp = fopen("./mysecret_root./pl.txt", "a");
	printf("input user name:\n");
	scanf("%s", a);
	printf("input user secret code\n");
	scanf("%s", b);

	if (strcmp(a, "k") == 0) {
		printf("用户名核对正确\n");
	} else {
		printf("用户名错误\n");
	}

	if (strcmp(b, "p") == 0) {
		printf("密码名核对正确\n");
	} else {
		printf("密码错误\n");
	}

//		rewind(fp);
	fseek(fp, SEEK_END, +1);	//	再基于end处向后移动一位
	if (	feof(fp) == 0) {
//			如果文件结束,则返回非0值,否则返回0
		printf("now file point in the end\n");
	}
//	直接使用时的错误分析:
//	对于一个空文件来说,当程序打开它的时候,它的光标会停在文件的开头,但是由于文件里什么内容都没有存(但是EOF是存在的),即整个文件就存贮了一个EOF。当程序打开文件,并直接调用feof()时,这个函数就会站在光标的位置向后张望,结果就看见了EOF,然后就当然返回0了。
//	————————————————
//	版权声明:本文为CSDN博主「konghouy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//	原文链接:https://blog.csdn.net/konghouy/article/details/80530937

}



void checkloginv2() {
	char a[100];
	char b[100];
	FILE* fp;
	fp = fopen("./mysecret_root./pl.txt", "a");
	printf("input user name:\n");
	scanf("%s", a);
	printf("input user secret code\n");
	scanf("%s", b);

//	if (strcmp(a, "k") == 0) {
//		printf("用户名核对正确\n");
//	} else {
//		printf("用户名错误\n");
//	}
//
//	if (strcmp(b, "p") == 0) {
//		printf("密码名核对正确\n");
//	} else {
//		printf("密码错误\n");
//	}
	user have[100];

	char c[10];
	int i = 0;
	for (i = 0; i < 10; i++) {
		c[0] = '0' + i;
		c[1] = '\0';
		strcpy(	have[i].acount, c);
		strcpy(have[i].code, c);
	}


	for (i = 0; i < 100; i++) {
		if (strcmp(a, have[i].acount) == 0) {
			printf("用户名核对正确\n");
			if (strcmp(b, have[i].code) == 0) {
				printf("密码正确\n");
			} else {
				printf("密码错误\n");
			}
			break;
		}
	}

	if (i == 100) {
		printf("用户名错误\n");
	}




//		rewind(fp);
	fseek(fp, SEEK_END, +1);	//	再基于end处向后移动一位
	if (	feof(fp) == 0) {
//			如果文件结束,则返回非0值,否则返回0
		printf("now file point in the end\n");
	}
//	直接使用时的错误分析:
//	对于一个空文件来说,当程序打开它的时候,它的光标会停在文件的开头,但是由于文件里什么内容都没有存(但是EOF是存在的),即整个文件就存贮了一个EOF。当程序打开文件,并直接调用feof()时,这个函数就会站在光标的位置向后张望,结果就看见了EOF,然后就当然返回0了。
//	————————————————
//	版权声明:本文为CSDN博主「konghouy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//	原文链接:https://blog.csdn.net/konghouy/article/details/80530937

}

//第一步复制粘贴,第二步,在改完之前的小函数之后,对checkorder内部函数加入v2后缀和括号内创建参数privatename,化原来新写函数变成一步一步就地替换函数,避免一开始思考架构。
//第三步参数改rootv2
//就着必然要的参数进行增加,对着框架一个个比着运行,自然而然写出
void checkorder(node* rootv2, char ch[], char privaterootname[]) {
	if (strcmp("cf", ch) == 0) {
		printf("Input file name:\n");
		scanf("%s", ch);
		printf("Input parent contest name:\n");
		char tar[100];
		scanf("%s", tar);
		findandaddv2(rootv2, 0, tar, ch, privaterootname);
		printf("success creat file\n");
	} else if (strcmp("cd", ch) == 0) {
		printf("Input dictionary name:\n");
		scanf("%s", ch);
		char tar[100];
		printf("Input parent contest name:\n");
		scanf("%s", tar);
		findadd_dirv2(rootv2, 0, tar, ch, privaterootname);
	} else if (strcmp("st", ch) == 0) {
		show(rootv2, 0, 10);
		printf("\ntree end\n");
		//			13.之后都是增加了删除之后,有了删除标志位后,显示函数,删除函数之类的操作,结构体更新
	} else if (strcmp("dead", ch) == 0) {
		printf("Input dead target name:\n");
		scanf("%s", ch);
		//			printf("Input dead parent name:\n");
		//			char tar[100];
		//			scanf("%s", tar);
		findanddead(rootv2, ch);
	} else if (strcmp("sthd", ch) == 0) {
		showhidedead(rootv2, 0, 30);
	} else if (strcmp("stwd", ch) == 0) {
		showwithdead(rootv2, 0, 35);
	} else {
		printf("commond not found\n");
	}

}



void registname(char privaterootname[]) {
//	FILE* fp;
//		fp = fopen("./mysecret_root./pl.txt", "a+");
//		fclose(fp);

	printf("请输入用户空间名\n");
	char headname[100];
	scanf("%s", headname);
	char *b = "./";

//	strcat(privaterootname, b);
	strcat(privaterootname, headname);
	char d[100] = "";

	strcat(d, b);
	strcat(d, privaterootname);
	strcat(d, b);
	strcat(d, "pl.txt");
	printf("%s\n", d);
	FILE* fp;
	fp = fopen(d, "a+");
	fclose(fp);
}


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";
		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);
	//	printf("input order\n");



		FILE* fp;
		fp = fopen("./mysecret_root./pl.txt", "a+");
		fclose(fp);

		*/
//	这是第一版的实现,固定文件头


//	加上相对路径,可以直接到文件夹里创建文件

//	fp = fopen("./mysecret_root./pl.txt","a");
//	printf("input user name:\n");
//	scanf("%s",a);
//	printf("input user secret code\n");
//	scanf("%s",b);
//
//	rewind(fp);

//	checklogin(a, b);

	char privaterootname[100] ;
	node* rootv2 = (node*)malloc(sizeof(node));
	checkloginv2();
	//如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm..
	registname(privaterootname);

	initv2(rootv2, privaterootname);
//	printf("rootv2 path is%s", rootv2->path);
	char a[100] = "n";
	char b[100] = "nwoevi";
//	printf("add dic\n");
	addDictionaryv2(rootv2, a, privaterootname);
	printf("dictionary ok!\n");


	addFilev2(rootv2, b, privaterootname);
	printf("File b ok!\n");

	char c[100] = "3894";
	addFilev2(rootv2, c, privaterootname);
	printf("File 3849 ok!\n");


	char d[100] = "floor2";
	addDictionaryv2(rootv2, d, privaterootname);


	char k[100] = "vnsn";
	findadd_dirv2(rootv2, 0, a, k, privaterootname);
	char f[100] = "ij";
	findandaddv2(rootv2, 0, k, f, privaterootname);


	char ch[100] = {};
	show(rootv2, 0, 10);



	printf("input order\n");
	while (1) {
//		gets(ch);
		scanf("%s", ch);
		if (strcmp("close", ch) == 0) {
			break;
		} else {
			checkorder(rootv2, ch, privaterootname);
		}

	}

//根目录./mysecret./
//名称./栈查找文件路径,
//然后写入
//字符分复制粘贴转字符串指针
	findandadd(rootv2, 0, "n", "newnode");
	show(rootv2, 0, 10);
	return 0;
}


//文件创建加前缀
//先解决二叉树,然后文件根目录,最后用户登录注册信息

大一点空白容易看到精简版本的代码的位置,这里就是精简代码了

精简版本代码:

1.舍弃痕迹,缓解信息量大和分辨符合需求的信息所造成的精力消耗

2.易于复制粘贴,以此移植。

3.方便统计有效代码,心情愉快

 

 

 复制粘贴直接跑,或者可以直接按ctrl+m分栏目对比DevC++文件树-windows下链表标记与标记节点的隐藏、重现-CSDN博客

 DevC++ C文件树 实现 用户文件前缀的自定义_第2张图片

 

 

#include
#include
#include
#include 
//解决13.里面的删除标记失败以及新增显示已删除的文件夹文件
//child->child->bro解决多个同级文件夹插入file文件,不能确认母节点问题
//解决文件加入a->child,实现子文件
//lenth-tab,解决文件打印竖线 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

int lenth = 20;
//文件类型后缀统一

typedef struct node {
//	文件树节点结构体
	char name[100];
//	节点名称,和路径不同,路径自动加入前缀,藏进了path里,printf 出来 可了解成员存储的内容
	char path[100];
//	10.版本出现文件创建,需要相对路径 ,path存储到上一级文件名+./,因为再加当前文件名,同级文件就会塞进下一个文件里
	int is_dictionary;
//	标志1:节点是文件夹:1,否则=0
	int is_dead = 0;
//	标志2:节点是标记删除的节点:1否则=0
	node* child;
	node* parent;
	node* bro;
} node;
node *root;

typedef struct user {
	char acount[100];
	char code[100];
} user;
//这是改secret_前缀的测试思路,成功穷举出矛盾。这个函数属于零起点,遇到矛盾,自然而然的理解,主要是找到这个并记录自然而然
//这个函数解决了如何判断前缀./的封装程度
void addprofix(char a[]) {

	char *b = "./mysecret_root./";
//		根节点加前缀
//		非根节点加后缀
//		只输入文件名,其他对外隐藏
	char *c = "./";
//		addbro ,在本层文件里,加在前缀
//		如 n->./mysecret_root./n
//			p->./mysecret_root./p


//		addchild,在下层文件里, 加后缀上
//			p->./mysecret_root./->./mysecret_root./n./p
//		后缀的./也一起存进去。名称之前,封装为路径,孩子之后,复制自己名称,在加入./作为路径。

//		addchild,在下层文件里, 上级文件名的加后缀上./
//			p->./mysecret_root./->./mysecret_root./n./ p


//	每个节点存上一个路径,不存自己的名字,
//	添加兄弟就直接复制粘贴,
//	添加孩子就再补充自己的名字,然后进入下一条。自然而然。

	//	默认创建在本地同文件里的mysecret_root文件里
	//	且直接输入名字即可创建
//		char a[100];
//		scanf("%s", a);
	char m[100] = {0};
	strcat(m, b);
	strcat(m, a);
	printf("%s\n", m);
}

int fun(char*filepath) {
	int res;
	//filepath为绝对路径
	//如果文件夹不存在
	if (_access(filepath, 0) != 0)
		//创建文件夹
		res = mkdir(filepath);// 返回 0 表示创建成功,-1 表示失败
	//remove(filename) 删除文件
	else
		res = 1;
	return res;
}
//map字母数字负责映射,或者符号数字负责映射
//然后switch case来直接跳转判断速度



void initv2(node* rootv2, char privaterootname[]) {
//	rootv2 = (node*)malloc(sizeof(node)); 如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
//	strcpy(root->path, "./mysecret_root");
	char *a = "./";
	char path[100] = {""};
	strcat(path, a);
	strcat(path, privaterootname);
	strcat(path, "_root");   //这是改出来的代码新增的一行/
	strcpy(rootv2->path, path);
	strcpy(rootv2->name, "root");
	rootv2->is_dead = 0;
	rootv2->parent = NULL;
	rootv2->child = NULL;
	rootv2->bro = NULL;
	rootv2->is_dictionary = 1;
	printf("%s\n", rootv2->path);
//	int flag = fun("./mysecret_root");
//	int	flag = fun(root->path);
//	if (flag == -1)
//		printf("创建失败\n");
//	else if (flag == 0)
//		printf("创建成功\n");
//	else if (flag == 1)
//		printf("文件夹已存在\n");
	int	flag = fun(rootv2->path);
	if (flag == -1)
		printf("磁盘根文件创建失败\n");
	else if (flag == 0)
		printf("磁盘根文件创建成功\n");
	else if (flag == 1)
		printf("磁盘根文件夹已存在\n");
}

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 addChildv2(node* parent, node* a, char privaterootname[]) {
//	printf("addChild path is a%s\n",a->path);		//debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
//	printf("parent path is %s",parent->path);  		 //debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	strcpy(a->path, parent->path);   //path是上级文件,所以下面需要./继续深入
//	人脑跑代码,跑到第二次发现,名字后面缺了./
//	意识到如果./在根文件开始,就会一直有这个二次文件沿用一次文件,复制粘贴一次,缺少下级./情况
//	于是按照二次文件改,看看这样在根文件创建的时候能不能适配
//	发现新创建的文件可以直接加上下级指令,根文件最后是名字,然后下次创建子文件,在子文件上在加上./

	strcat(a->path, "./");  //下层指令,此时才算进入下层
	strcat(a->path, privaterootname);
	strcat(a->path, "_");
//	strcat(a->path, "mysecret_");      替换固定头文件。 其他不思考。 回头再按之前的mysecret_实现的思路重复一遍,加前缀后重复一遍,留前缀去后缀替换后再重复一遍。
	strcat(a->path, a->name);

//古早注释在新的需求下有了新的含义,复用穷举法
//	下面三次循环可以看成从根节点开始,连续三次创建文件,三层文件名都间隔了一个./符合路径格式,一切正常
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//
//	strcat(a->path, "./");  //下层指令
//	strcat(a->path, a->name);
//	printf("check add head now a is %s\n", a->path);		//debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	if (a->is_dictionary) {

		fun(a->path);
	} else {
		strcat(a->path, ".txt");
		FILE* fp;
		fp = fopen(a->path, "w");
		fclose(fp);
	}

	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 format(node *a, int tab, int see) {
//	printf("%-18s", a->name);
//	for (int i = 0; i < see - tab; i++) {
//		printf(" ");
//	}
//	printf("%-9s", "dictionary");
//
//}

void addFilev2(node* parent, char a[], char privaterootname[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 0;
	p->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//	addbro(parent, p);
//	printf("add function is running\n");

	addChildv2(parent, p, privaterootname);     //重写的另一种情况:从注释一行代码到 复制粘贴代码块,代码块里面的函数直接加新的参数。
//	核心函数增加参数 ,其他嵌套函数增加相同参数,可以借此形成线索,这个新思想的背景,则是来源于相同代码的复制粘贴,修改参数。
// 从改一个函数一个参数到改两个函数一个参数
//从改两个函数一个参数到改两个嵌套函数一个参数
//再到新增功能,新增自定义功能时,各个函数新增相同参数作为控制
//再到模块移植,从一个功能实现到模块化,就是把原来的主函数变成某个小函数,原来主函数需要的变量,全部放进小函数里。
//这就是新功能实现的无中生有的流程,纯纯一个一个函数加参数 ,改的多了,规模大了,遇着的函数与函数之间的联系,自然而然描述出来修改思路。

//	printf("success creat file\n");
}


void addDictionaryv2(node* parent, char a[], char privaterootname[]) {
	node* p = (node*)malloc(sizeof(node));
	strcpy(p->name, a);
	p->is_dictionary = 1;
	p->is_dead = 0;
	p->bro = NULL;
	p->child = NULL;
	p->parent = NULL;
//		addbro(parent, p);
//	printf("add function is running\n");       //debug记录:如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm.
	addChildv2(parent, p, privaterootname);
//	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", a->name);
			for (int i = 0; i < lenth - tab; i++) {
				printf(" ");
			}
			printf("%-9s\n", "dictionary");
//			printf("-%-18s  %-3s\n", a->name, "dictonary");
//			左对齐缩进
			show(a->child, tab + 5, head);
		} else {
//			format(a->name,tab,lenth);

			printf("%-18s", a->name);
//			左对齐18长度,lenth=20被挤出,lenth=30不会超出
			for (int i = 0; i < lenth - tab; i++) {
				printf(" ");
			}
//				printf("%-5d", tab);
			printf("%-9s\n", "");
//			printf("-%-7s  %-s\n", a->name, "");
		}
		a = a->bro;
	}
}

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

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

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


void findandaddv2(node* list, int floor, char name[], char have[], char privaterootname[]) {
	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");
				addFilev2(a, have, privaterootname);
				return ;
			}
			findandaddv2(a->child, 0, name, have, privaterootname);
//		show(a->child, floor + 1);
		} else {
			if (strcmp(a->name, name) == 0) {
				printf("FIND name\n");
				addFilev2(a, have, privaterootname);
				return ;
			}
		}
		a = a->bro;
	}
//需要控制只要查到,递归就不再做其他运算,直接退出,加结构体
}


//优化版本-增加文件夹
void findadd_dirv2(node* list, int floor, char name[], char have[], char privaterootname[]) {
	node *a = list;

	while (a != NULL) {
		if (a->is_dictionary) {
//			printf("-checking dictionary-%s\n", a->name);
			if (strcmp(a->name, name) == 0) {
				printf("FIND name %s\n", a->name);
				addDictionaryv2(a, have, privaterootname);
				return ;
			}

			findadd_dirv2(a->child, 0, name, have, privaterootname);

		} else {

		}
		a = a->bro;
	}
}



//void changename(node* list, char have[]) {
	node *a = list;
	node *prior;
	node *dead = a;
	char newname[100];
	char *deadsign = "dead_";
	strcat(newname, deadsign) ;
	strcat(newname, dead->name);
	rename(dead->name, newname);
//
//	node *a = list;
//	rename(a->name, have);
//}

//void deadsignshow(node* list) {
//	node *a = list;
//	node *dead = a;
//	char newname[100];
//	char *deadsign = "dead_";
//	strcat(newname, deadsign) ;
//	strcat(newname, dead->name);
//	rename(dead->name, newname);
//}

void deadaddsign_v2(node* list) {
//	node* a=list->child
//	node* a=list;
	node* a = list->child;
	while (a != NULL) {
		if (a->is_dictionary) {
			a->is_dead = 1;
//				deadsignv2(a);
//			deadaddsign_v2(a->child);
			deadaddsign_v2(a);
		} else {
			a->is_dead = 1;
		}
		a = a->bro;
//		因为传入本级bro,所以要a=list->child,不然list-bro就会一块标记
	}
}

//
//void deadChild(node* list) {
//	node *a = list;
//	node *prior;
//	node *dead;
//	//	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 ;
			}
//			deadChild(a->child);
//			//		show(a->child, floor + 1);
//		} else {
//			while (a != NULL) {
//				prior = a;
//				if (a->bro->is_dictionary == 1) {
//
					if(a->bro->child==NULL){
						dead=a->bro;
						a->bro=dead->bro;
						free(a);
					}
//				} else {
//					dead = a->bro;
//					char *deadsign = "dead_";
//					char newname[100];
//
//					strcat(newname, deadsign) ;
//					strcat(newname, dead->name);
//					rename(dead->name, newname);
					remove(dead->path);
//
//				}
//
//			}
//		}
//		prior = a;
//		a = a->bro;
//	}
//}


void findanddead(node* list, char have[]) {
	node *a = list->child;
	//	int tab = floor;
	while (a != NULL) {
		if (a->is_dictionary) {
			if (strcmp(a->name, have) == 0) {
				printf("FIND name\n");
				addFile(a, have);
				a->is_dead = 1;
				deadsignv2(a->child);
				a->is_dead = 1;
				deadaddsign_v2(a);
				v2到_v2,封装当前目录先标记,然后再进入child进行修改
				return ;
			} else {
				if (a->child != NULL) {
					findanddead(a->child, have);
				}
			}
			//		show(a->child, floor + 1);
		} else {
			if (strcmp(a->name, have) == 0) {
				printf("FIND name\n");
//				addFile(a, have);
				a->is_dead = 1;
				return ;
			}
		}
		a = a->bro;
	}
}

//复制粘贴自show()函数,隐藏删除文件
void showhidedead(node* list, int floor, int head) {
//	node *a = list->child;
	node *a = list;
	int tab = floor;
	while (a != NULL) {
		if (a->is_dead) {
			a = a->bro;
			continue;
		} else {
			for (int i = 0; i < head + 20; i++) {
				printf("^");
			}
			floor = tab;
			while (floor > 0) {
				if (floor % 5 == 1) {
					printf("|");
				} else {
					printf(" ");
				}
				floor--;
			}
			if (a->is_dictionary) {
				printf("%-18s", a->name);
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "dictionary");
				if (a->child != NULL) {
					showhidedead(a->child, tab + 5, head);
				}
			} else {
				printf("%-18s", a->name);
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "");
			}
			a = a->bro;
		}
	}
}

//显示删除文件,并且打印标记已经删除的文件前缀
void showwithdead(node* list, int floor, int head) {
	node *a = list;
	int tab = floor;
	while (a != NULL) {
//		if (a->is_dead) {
//			a = a->bro;
//			deadsignshow(a);
//			continue;
//		} else
		{
			for (int i = 0; i < head + 20; i++) {
				printf("^");
			}
			floor = tab;
			while (floor > 0) {
				if (floor % 5 == 1) {
					printf("|");
				} else {
					printf(" ");
				}
				floor--;
			}
			if (a->is_dictionary) {
				if (a->is_dead) {
					char newname[100];
					char *deadsign = "dead_";
					strcat(newname, deadsign) ;
					strcat(newname, a->name);

					printf("%-18s", newname);
					//				printf("%-18s", a->name);
				} else {
					printf("%-18s", a->name);
				}
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "dictionary");
				showwithdead(a->child, tab + 5, head);
			} else {
				if (a->is_dead) {
					char newname[100];
					char *deadsign = "dead_";
					strcat(newname, deadsign) ;
					strcat(newname, a->name);

					printf("%-18s", newname);
					//				printf("%-18s", a->name);
				} else {
					printf("%-18s", a->name);
				}
				for (int i = 0; i < lenth - tab; i++) {
					printf(" ");
				}
				printf("%-9s\n", "");
			}
			a = a->bro;
		}
	}
}


void checkloginv2() {
	char a[100];
	char b[100];
	FILE* fp;
	fp = fopen("./mysecret_root./pl.txt", "a");
	printf("input user name:\n");
	scanf("%s", a);
	printf("input user secret code\n");
	scanf("%s", b);

//	if (strcmp(a, "k") == 0) {
//		printf("用户名核对正确\n");
//	} else {
//		printf("用户名错误\n");
//	}
//
//	if (strcmp(b, "p") == 0) {
//		printf("密码名核对正确\n");
//	} else {
//		printf("密码错误\n");
//	}
	user have[100];

	char c[10];
	int i = 0;
	for (i = 0; i < 10; i++) {
		c[0] = '0' + i;
		c[1] = '\0';
		strcpy(	have[i].acount, c);
		strcpy(have[i].code, c);
	}


	for (i = 0; i < 100; i++) {
		if (strcmp(a, have[i].acount) == 0) {
			printf("用户名核对正确\n");
			if (strcmp(b, have[i].code) == 0) {
				printf("密码正确\n");
			} else {
				printf("密码错误\n");
			}
			break;
		}
	}

	if (i == 100) {
		printf("用户名错误\n");
	}


//		rewind(fp);
	fseek(fp, SEEK_END, +1);	//	再基于end处向后移动一位
	if (	feof(fp) == 0) {
//			如果文件结束,则返回非0值,否则返回0
		printf("now file point in the end\n");
	}
//	直接使用时的错误分析:
//	对于一个空文件来说,当程序打开它的时候,它的光标会停在文件的开头,但是由于文件里什么内容都没有存(但是EOF是存在的),即整个文件就存贮了一个EOF。当程序打开文件,并直接调用feof()时,这个函数就会站在光标的位置向后张望,结果就看见了EOF,然后就当然返回0了。
//	————————————————
//	版权声明:本文为CSDN博主「konghouy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//	原文链接:https://blog.csdn.net/konghouy/article/details/80530937

}


//第一步复制粘贴,第二步,在改完之前的小函数之后,对checkorder内部函数加入v2后缀和括号内创建参数privatename,化原来新写函数变成一步一步就地替换函数,避免一开始思考架构。
//第三步参数改rootv2
//就着必然要的参数进行增加,对着框架一个个比着运行,自然而然写出
void checkorder(node* rootv2, char ch[], char privaterootname[]) {
	if (strcmp("cf", ch) == 0) {
		printf("Input file name:\n");
		scanf("%s", ch);
		printf("Input parent contest name:\n");
		char tar[100];
		scanf("%s", tar);
		findandaddv2(rootv2, 0, tar, ch, privaterootname);
		printf("success creat file\n");
	} else if (strcmp("cd", ch) == 0) {
		printf("Input dictionary name:\n");
		scanf("%s", ch);
		char tar[100];
		printf("Input parent contest name:\n");
		scanf("%s", tar);
		findadd_dirv2(rootv2, 0, tar, ch, privaterootname);
	} else if (strcmp("st", ch) == 0) {
		show(rootv2, 0, 10);
		printf("\ntree end\n");
		//			13.之后都是增加了删除之后,有了删除标志位后,显示函数,删除函数之类的操作,结构体更新
	} else if (strcmp("dead", ch) == 0) {
		printf("Input dead target name:\n");
		scanf("%s", ch);
		//			printf("Input dead parent name:\n");
		//			char tar[100];
		//			scanf("%s", tar);
		findanddead(rootv2, ch);
	} else if (strcmp("sthd", ch) == 0) {
		showhidedead(rootv2, 0, 30);
	} else if (strcmp("stwd", ch) == 0) {
		showwithdead(rootv2, 0, 35);
	} else {
		printf("commond not found\n");
	}

}



void registname(char privaterootname[]) {
//	FILE* fp;
//		fp = fopen("./mysecret_root./pl.txt", "a+");
//		fclose(fp);

	printf("请输入用户空间名\n");
	char headname[100];
	scanf("%s", headname);
	char *b = "./";

//	strcat(privaterootname, b);
	strcat(privaterootname, headname);
	char d[100] = "";

	strcat(d, b);
	strcat(d, privaterootname);
	strcat(d, b);
	strcat(d, "pl.txt");
	printf("%s\n", d);
	FILE* fp;
	fp = fopen(d, "a+");
	fclose(fp);
}


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";
		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);
	//	printf("input order\n");



		FILE* fp;
		fp = fopen("./mysecret_root./pl.txt", "a+");
		fclose(fp);

		*/

//	这是第一版的实现,固定文件头


//	加上相对路径,可以直接到文件夹里创建文件

//	fp = fopen("./mysecret_root./pl.txt","a");
//	printf("input user name:\n");
//	scanf("%s",a);
//	printf("input user secret code\n");
//	scanf("%s",b);
//
//	rewind(fp);

//	checklogin(a, b);


	char privaterootname[100] ;
	node* rootv2 = (node*)malloc(sizeof(node));
	checkloginv2();
	//如果rootv2 是空的,在函数内部初始化时,数据就不能传出去emm..
	registname(privaterootname);

	initv2(rootv2, privaterootname);
//	printf("rootv2 path is%s", rootv2->path);
	char a[100] = "n";
	char b[100] = "nwoevi";
//	printf("add dic\n");
	addDictionaryv2(rootv2, a, privaterootname);
	printf("dictionary ok!\n");


	addFilev2(rootv2, b, privaterootname);
	printf("File b ok!\n");

	char c[100] = "3894";
	addFilev2(rootv2, c, privaterootname);
	printf("File 3849 ok!\n");


	char d[100] = "floor2";
	addDictionaryv2(rootv2, d, privaterootname);


	char k[100] = "vnsn";
	findadd_dirv2(rootv2, 0, a, k, privaterootname);
	char f[100] = "ij";
	findandaddv2(rootv2, 0, k, f, privaterootname);


	char ch[100] = {};
	show(rootv2, 0, 10);



	printf("input order\n");
	while (1) {
//		gets(ch);
		scanf("%s", ch);
		if (strcmp("close", ch) == 0) {
			break;
		} else {
			checkorder(rootv2, ch, privaterootname);
		}

	}

//根目录./mysecret./
//名称./栈查找文件路径,
//然后写入
//字符分复制粘贴转字符串指针
	findandaddv2(rootv2, 0, "n", "newnode",privaterootname);
	show(rootv2, 0, 10);
	return 0;
}


//文件创建加前缀
//先解决二叉树,然后文件根目录,最后用户登录注册信息

 

你可能感兴趣的:(c++,开发语言)