基于之前的文件树改写,排版文件类型格式,统一缩进
增加硬盘创建文件夹,.txt文件
增加一个用户名,密码。
复制粘贴就能跑
#include
#include
#include
#include
//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];
char path[100];
// 10.版本出现文件创建,需要相对路径 ,path存储到上一级文件名+./,因为再加当前文件名,同级文件就会塞进下一个文件里
int is_dictionary;
node* child;
node* parent;
node* bro;
} node;
node *root;
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->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 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 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);
// 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->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");
//
//}
//先就着基本有的直接敲上,然后打印递归的时候发现传进指针,一开始的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 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
}
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);
printf("input order\n");
while (1) {
// gets(ch);
scanf("%s", ch);
if (strcmp("close", ch) == 0) {
break;
} else 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);
findandadd(root, 0, tar, ch);
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_dir(root, 0, tar, ch);
} else if (strcmp("st", ch) == 0) {
show(root, 0, 10);
printf("\ntree end\n");
} else {
printf("commond not found\n");
continue;
}
}
//根目录./mysecret./
//名称./栈查找文件路径,
//然后写入
//字符分复制粘贴转字符串指针
findandadd(root, 0, "n", "newnode");
show(root, 0, 10);
return 0;
}
//文件创建加前缀
//先解决二叉树,然后文件根目录,最后用户登录注册信息