课程设计【操作系统】:【文件管理系统设计】(包含完整代码)

您所在的位置:网站首页 简单的文件系统c语言怎么写出来 课程设计【操作系统】:【文件管理系统设计】(包含完整代码)

课程设计【操作系统】:【文件管理系统设计】(包含完整代码)

2024-07-09 13:07| 来源: 网络整理| 查看: 265

文章目录 课程设计题目1. 设计内容1.1 基本命令设计1.2 基本数据结构设计 1.3 基本命令的程序流程图 1) 用户注册:register2) 用户登录:login3) 创建文件:create(文件名)4) 创建文件夹:mkdir(文件夹名)5) 打开文件:open(文件名)6) 关闭文件:close(文件名)7) 读取文件:read(文件名)8) 删除文件:del(文件名)9) 删除目录:remove(文件名)10) 切换目录:cd11) 列文件目录:dir12) 显示当前目录的文件:ls13) 写入文件:write14) 修改文件属性:change(文件名) 2. 结果 & 简要分析 2.1 用户注册:register2.2 用户登录:login2.3 创建文件:create(文件名)2.4 创建文件夹:mkdir(文件夹名)2.5 打开文件:open(文件名)2.6 关闭文件:close(文件名)2.7 读取文件:read(文件名)2.8 删除文件:del(文件名)2.9 删除目录:remove(文件名)2.10 切换目录:cd2.11 列文件目录:dir2.12 显示当前目录的文件:ls2.13 写入文件:write2.14 修改文件属性:change(文件名)2.15 清屏:clear2.16 显示所有的命令:help2.17 退出系统:exit 3. 总结分析3.1 遇到的问题3.2 解决方法3.3 设计需要改进的内容3.4 个人收获与感想 4. 完整代码 4.1 windows版本代码4.2 linux版本代码

文章末尾有完整可运行代码,希望点赞支持一下。

课程设计题目

文件管理系统设计: 通过模拟文件操作命令的执行,来模拟文件管理。要求建立相应的数据结构:文件控制块、空闲盘块等,模拟盘块管理能够实现文件的建立、打开、读写、执行、属性修改、文件保护等基本功能。

1. 设计内容 1.1 基本命令设计 用户注册:register用户登录:login创建文件:create(文件名)创建文件夹:mkdir(文件夹名)打开文件:open(文件名)关闭文件:close(文件名)读取文件:read(文件名)删除文件:del(文件名)删除目录:remove(文件名)切换目录:cd列文件目录:dir显示当前目录的文件:ls写入文件:write(文件名,物理块要存入的数据内容,文件内数据总长度)修改文件属性:change(文件名)清屏:clear显示所有的命令:help退出系统:exit 1.2 基本数据结构设计

1) (第一级)顶层目录 MFD

string username; //用户名 string password; //登录密码 struct USER_UFD *next; //指向用户目录

2) (第二级)单个用户的文件目录 USER_UFD

struct UFD direct[16]; //每个用户最多有16个目录 int cur_user_direct_size = 0; //当前用户的目录数

3) (第三层)用户的某个目录文件下的所有文件(包含一个用户的所有文件) UFD

string directname; //用户目录名(文件夹的名称) int cur_file_size = 0; //不能在结构体内附初始值。 file_message ufd[64]; //每个文件夹下可以有64个文件

4) 第三层中的文件结构体 file_message

string filename; //文件名 int protect_code; //保护码 int length; //文件长度 int addr; //存放该文件的物理块的第一个的块号

5) 当前打开的文件控制块 UOF

int cur_openfilesize = 0; //打开的文件数 uof uof[16] //最多16个文件

6) 当前打开的文件结构体 uof

string filename;//文件名 int pointer; //文件的读写指针,其实就是文件的大小 int protect_code; //2表示可读可写,1表示可读不可写, 0表示不可读不可写 int addr; //存放文件的第一个磁盘块号

7) 文件分配表 fat

int next = -1; //下一个磁盘块号 int used = 0; //1表示被使用,0表示未被使用 //注:用一块物理块存放,那么最多可以记录64块数据块的信息。记录文件占用磁盘块情况:物理块,假设一个磁盘的每个物理块大小为 512个字节 = 64*2*4字节。

整体结构的手写草稿图:

在这里插入图片描述

1.3 基本命令的程序流程图

注:本文中 name 均代表 文件名(或文件目录)

1) 用户注册:register

在这里插入图片描述 图1.1 register命令的流程图

2) 用户登录:login

在这里插入图片描述 图1.2 login命令的流程图

3) 创建文件:create(文件名)

在这里插入图片描述 图1.3 create命令的流程图

4) 创建文件夹:mkdir(文件夹名)

在这里插入图片描述 图1.4 mkdir命令的流程图

5) 打开文件:open(文件名)

在这里插入图片描述 图1.5 open命令的流程图

6) 关闭文件:close(文件名)

在这里插入图片描述 图1.6 close命令的流程图

7) 读取文件:read(文件名)

在这里插入图片描述图1.7 read命令的流程图

8) 删除文件:del(文件名)

在这里插入图片描述 图1.8 del命令的流程图

9) 删除目录:remove(文件名)

在这里插入图片描述 图1.9 remove命令的流程图

10) 切换目录:cd

在这里插入图片描述 图1.10 cd命令的流程图

11) 列文件目录:dir

在这里插入图片描述 图1.11 dir命令的流程图

12) 显示当前目录的文件:ls

在这里插入图片描述 图1.12 ls命令的流程图

13) 写入文件:write

在这里插入图片描述 图1.13 write命令的流程图

14) 修改文件属性:change(文件名)

在这里插入图片描述 图1.14 change命令的流程图

2. 结果 & 简要分析 2.1 用户注册:register

实现结果: 在这里插入图片描述 图2.1 register运行结果

设计思路:

首先系统提示用户输入用户名以及密码,如果用户输入的用户名没有重复,即可成功注册。如果遇到用户名重复的情况,那么系统会提示“用户已经存在”。 2.2 用户登录:login

实现结果: 在这里插入图片描述 图2.2.1 login成功登陆运行结果 在这里插入图片描述图2.2.2 login登陆信息验证

设计思路:

如图2.2.1所示,当用户正确输入用户名和密码时,可以成功登录进系统,但是如图2.2.2所示,当用户输入的用户名或者用户密码任意一个出现错误,那么系统会提示没有该用户或者密码错误。 2.3 创建文件:create(文件名)

实现结果: 在这里插入图片描述 图2.3 create命令在目录下创建文件

设计思路:

图2.3展示了使用create命令创建文件的过程,当用户在非文件夹下创建普通文件时,将会遇到提示“当前不处于文件目录下,请在文件夹下创建文件”,当用户进入某个文件夹下(比如文件夹a),那么用户就可以创建不同后缀的文件,同时创建的文件上限是64个。 2.4 创建文件夹:mkdir(文件夹名)

实现结果: 在这里插入图片描述图2.4 mkdir命令创建目录结果

设计思路: 每当创建一个新的文件夹: • 修改USER_UFD类型的成员cur_user_direct_size+1 • 初始化USER_UFD类型的成员ufd,初始化为文件夹名为name • 初始化USER_UFD类型的成员ufd,初始化文件数为零。

2.5 打开文件:open(文件名)

实现结果: 在这里插入图片描述 图2.5 文件打开测试结果

设计思路:

每次打开文件都需要判断文件是否存在,同时文件如果已经被打开,那么就提示“文件已经打开”,然后再更新文件打开表信息:cur_openfilesize++文件打开数量加1(保存被打开文件的信息)。 只有打开的文件,才能进行相应的读写等下一步操作。 2.6 关闭文件:close(文件名)

实现结果: 在这里插入图片描述图2.6 close命令文件关闭命令测试结果

设计思路:

首先判断文件是否打开,以防止文件还处于操作过程中时,就被无意删除。当文件处于打开状态打开,才能被关闭。 2.7 读取文件:read(文件名)

实现结果: 在这里插入图片描述图2.7 read命令文件读取测试结果

设计思路:

首先如过一个文件没有打开,那么就不能被读取;第二步展示了打开文件后,进一步才能进行读取操作。从图2.7中可以看到,文件中的内容成功被读取到了命令行中。 2.8 删除文件:del(文件名)

实现结果: 在这里插入图片描述 图2.8 del删除文件命令测试结果

设计思路:

文件删除的测试结果如图2.8所示,当用户输入命令del想要删除“不存在”的文件或者想要删除“被打开”的文件时,系统就会阻止删除操作的进一步进行。 2.9 删除目录:remove(文件名)

实现结果: 在这里插入图片描述图2.9 remove命令的测试结果

设计思路:

当用户输入命令remove,系统可以将当前文件夹及其包含的所有文件删除掉。 2.10 切换目录:cd

实现结果: 在这里插入图片描述图2.10 cd命令的测试结果

设计思路:

使用cd命令可以切换路径,包扩修改path等。从而实现了路径的切换。“…”代表返回上级目录,这里功能是通过判断语句,将path的值修改为空,直接跳转到根目录,因为目录层级只有两级,所以可以这样操作。 2.11 列文件目录:dir

实现结果: 在这里插入图片描述 图2.11 dir命令测试结果

设计思路:

dir命令如果是在目录层进行使用,那么就会显示所有创建好的文件夹,如果是在文件夹中使用,那么将会显示当前文件夹下所有文件的属性信息。 2.12 显示当前目录的文件:ls

实现结果: 在这里插入图片描述 图2.12 ls命令的测试结果

设计思路:

ls可以将当前目录或者文件列出,效果如图2.12所示。 2.13 写入文件:write

实现结果: 在这里插入图片描述 图2.13 向1.txt中写入数据测试结果

设计思路:

如图2.13所示,当用户使用write,系统会提示用户输入想要写入信息的文件名,文件没有打开就无法读取文件,也不能写入数据。向文件中写入信息时,使用获取行得到用户输入的信息,因为回车键是确认信息写入(写信息是追加的方式)。 2.14 修改文件属性:change(文件名)

实现结果: 在这里插入图片描述 2.14 change命令的测试结果

设计思路:

从图2.14中可以看到,第一步显示了文件的信息,从表中可以详细的看到每个文件的名称、保护码、文件长度、文件起始物理盘块号等信息。当用户使用change命令修改某个文件,需要选择对应的修改项,图中步骤4和步骤5展示了修改文件属性名后的结果,同时文件的属性修改还支持文件保护码的修改。 2.15 清屏:clear

实现结果: 在这里插入图片描述 图2.15.1 运行clear之前 在这里插入图片描述 图2.15.2 运行clear之后

设计思路:

根据图2.15.1和图2.15.2对比,可以看出程序运行完,命令行被清空,这同时会导致所有的文件被自动关闭,所以再次进行文件相关操作时,需要重新打开文件。 2.16 显示所有的命令:help

实现结果: 在这里插入图片描述 图2.16 help命令的测试结果

设计思路:

当用户输入命令help时,如图2.16所示,系统将会打印命令菜单。 2.17 退出系统:exit

实现结果: 文件系统释放内存,程序关闭

设计思路:

当用户输入命令exit,系统将会退出,同时清空占用的缓存,释放系统资源。 3. 总结分析 3.1 遇到的问题 实现文件控制块、空闲盘块等数据结构相对较为复杂。文件的打开、关闭、读写、修改属性等操作实现起来比较繁琐。在设计过程中需要考虑多用户、多目录、多文件的情况,容易出现数据混乱。 3.2 解决方法 第一个问题,可以通过前置课程的学习和查阅资料等方式深入了解和掌握数据结构的知识点,并根据实际需求灵活应用。第二个问题,可以通过封装函数来简化操作,同时加强代码的可读性和可维护性。第三个问题,可以采用各种数据结构来提高程序的鲁棒性,例如采用链表等数据结构。 3.3 设计需要改进的内容 在文件控制块、UFD、UOF等数据结构的设计中,应该加入更多的属性和方法,使得系统功能更加完善。在用户交互方面,可以引入图形界面等方式,提高用户操作的便利性和用户体验。 3.4 个人收获与感想 通过这次课程设计,我对于数据结构和文件操作有了更深入的理解。同时,也提高了自己的编程能力和解决问题的能力。最重要的是,这次经历让我更深刻地认识到了操作系统的魅力和挑战,同时也让我愈发热爱这个领域。 4. 完整代码

包含详细注释的代码如下,可运行。

两个版本的代码基本没有区别,不同之处在于清屏操作。

除了clear和exit命令有系统调用,其他功能均没有系统函数调用。

4.1 windows版本代码

fileSystem.cpp

//--------------------------------【文件管理】--------------------------------// //文件管理系统设计:通过模拟文件操作命令的执行,来模拟文件管理。 // //要求建立相应的数据结构:文件控制块、空闲盘块等。 // //模拟盘块管理能够实现文件的建立、打开、读写、执行、属性修改、文件保护等基本功能。 // //---------------------------------------------------------------------------// //#include // 定义了一些控制台操作函数,例如getch、clrscr和gotoxy等。这些函数只在Windows平台上可用,在Linux或macOS上不可用。 #include // 标准输入输出头文件,包含cout,cin等 #include // 定义了字符串类string #include // 定义了输入输出函数,例如printf #include // 定义了一些常用的函数和变量类型,例如malloc、exit、size_t和NULL等 #include // 获取当前系统时间,用于记录文件创建时间等信息。 using namespace std; //命名空间std //函数声明 void register_user(); //1.用户注册 int login(); //2.登录,返回用户在用户目录数组中的下标 int create(string); //3.文件创建(文件名) void mkdir(string); //4.创建文件夹(文件夹名) int open(string name); //5.打开文件(文件名) int close(string); //6.关闭文件(文件名) int read(string); //7.读取文件(文件名) int del(string); //8.删除文件(文件名) void remove(string name);//9.删除目录(文件名) void cd(); //10.切换目录 void dir(); //11.列文件目录 void ls(); //12.显示当前目录的文件 int write(string, char *, int); //13.写入文件(文件名,物理块要存入的数据内容,文件内数据总长度) void change(string name);//14.修改文件属性(文件名) void input_operation(); //用户交互 void display(); //列出所有命令以及用法 bool login_or_not(); //检测是否有用户登录 //-------第一级:顶层目录(所有的用户) struct MFD // 16个用户-----------------------2的幂次方 { string username; //用户名 string password; //登录密码 struct USER_UFD *next; //指向用户目录 }; //-------第三层:用户的某个目录文件下的所有文件(包含一个用户的所有文件) struct UFD //一个用户可以用16个文件夹 { struct file_message //每个文件夹下可以有64个文件 { string filename; //文件名 int protect_code; //保护码 int length; //文件长度 int addr; //存放该文件的物理块的第一个的块号 }ufd[64]; string directname; //用户目录名(文件夹的名称) int cur_file_size = 0; //不能在结构体内附初始值。 }; //-------第二级:单个用户的文件目录 struct USER_UFD { struct UFD direct[16]; //每个用户最多有16个目录 int cur_user_direct_size = 0; //当前用户的目录数 }; // user open file:当前打开的文件控制块 struct UOF //假设一个用户最多同时打开16个文件 { struct uof { string filename;//文件名 int pointer; //文件的读写指针,其实就是文件的大小 int protect_code; //2表示可读可写,1表示可读不可写, 0表示不可读不可写 int addr; //存放文件的第一个磁盘块号 }uof[16]; int cur_openfilesize = 0; //打开的文件数 }; //-------记录文件占用磁盘块情况:物理块,假设一个磁盘的每个物理块大小为 512个字节 = 64*2*4字节 struct fat //文件分配表 用一块物理块存放,那么最多可以记录64块数据块的信息。 { int next = -1; //下一个磁盘块号 int used = 0; //1表示被使用,0表示未被使用 }fat[64]; int max_usersize = 16; //最大用户数量 int max_userfilesize = 64; //每个用户最大文件夹数量 int max_openfilesize = 16; //用户可以同时打开的文件数量 MFD mfd[16]; //-------用户信息:16个用户(身份登录信息) USER_UFD cur_all_direct[16]; //-------第一级:16个用户的所有目录的对象(文件目录信息) MFD cur_user; //-------第二级:当前用户,可检索到当前用户下所有的目录(同时只能有一个用户处于登录状态) UOF openfile[16]; //当前用户的文件打开表对象,为全局变量 UOF *cur_opentable; //指向当前文件打开表 char *fdisk; //虚拟磁盘的起始位置 int cur_user_size = 0; //记录当前用户的人数(上限16) string path; //记录当前用户的路径 bool login_or = false; //记录当前是否有用户登录 //文件创建 int create(string name) { // 0 判断当前路径 if(path == "") { cout direct[index].directname) //判断 { break; } } // 2 文件重名判断 int i; for (i = 0; i < cur_user.next->direct[index].cur_file_size; i++) //遍历当前目录,查看是否有文件重名 { if (name == cur_user.next->direct[index].ufd[i].filename) break; } if (i < cur_user.next->direct[index].cur_file_size) //判断文件名是否重复 { cout direct[index].cur_file_size].addr = j; //文件起始盘块号 cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size].length = 0; //文件初始没有数据 cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size].protect_code = 2; //表示可读可写 cur_user.next->direct[index].cur_file_size++;//用户文件数量加1 fat[j].used = 1; //被使用 fat[j].next = -1; //只是个空文件,所有没有后序的块 //写入文件打开表中,就是调用open() cout cur_user_direct_size; index++) { if (path == cur_user.next->direct[index].directname) //找指定名称的目录 { break; } } // 2 遍历该文件夹下的文件,获取文件下标 //cur_user.next->direct[index].cur_file_size 代表 文件数 int i; for (i = 0; i < cur_user.next->direct[index].cur_file_size; i++) //当前目录有没有这个文件,没有就自然不能打开 { if (name == cur_user.next->direct[index].ufd[i].filename) break; } // 3 判断文件是否存在 //-------这里的判断应当是大于等于,而不是大于 if (i >= cur_user.next->direct[index].cur_file_size) { cout 打开的文件数 if (cur_opentable->cur_openfilesize == max_openfilesize) //如果打开文件的数量达到最大值,那么就无法打开 { cout uof[j].filename == name) { cout direct[index].cur_file_size; k++) //找到要打开的文件在文件数组中的第几个 { if (cur_user.next->direct[index].ufd[k].filename == name) break; } //打开文件:更新打开表(保存被打开文件的信息), cur_opentable->uof[cur_opentable->cur_openfilesize].filename = name; cur_opentable->uof[cur_opentable->cur_openfilesize].protect_code = cur_user.next->direct[index].ufd[k].protect_code; cur_opentable->uof[cur_opentable->cur_openfilesize].pointer = cur_user.next->direct[index].ufd[k].length; cur_opentable->uof[cur_opentable->cur_openfilesize].addr = cur_user.next->direct[index].ufd[k].addr; cur_opentable->cur_openfilesize++; //文件打开数量加1 cout cur_user_direct_size; index++) { if (path == cur_user.next->direct[index].directname) //找指定名称的目录 { break; } } // 2 遍历该文件夹下的文件 //cur_user.next->direct[index].cur_file_size 代表 文件数 int i; for (i = 0; i < cur_user.next->direct[index].cur_file_size; i++) //当前目录有没有这个文件,没有就自然不能打开 { if (name == cur_user.next->direct[index].ufd[i].filename) break; } // 3 判断文件是否存在 //-------这里的判断应当是大于等于,而不是大于 if (i >= cur_user.next->direct[index].cur_file_size) { cout name; //文件名 cur_user.next->direct[index].ufd[i].filename = name; } if(which == 2) { cout > code; //读写权限 if(code == 0 || code == 1 || code == 2 ) cur_user.next->direct[index].ufd[i].protect_code = code; else cout cur_openfilesize) { cout uof[cur_opentable->cur_openfilesize - 1].filename; cur_opentable->uof[fd].pointer = cur_opentable->uof[cur_opentable->cur_openfilesize - 1].pointer; cur_opentable->uof[fd].protect_code = cur_opentable->uof[cur_opentable->cur_openfilesize - 1].protect_code; cur_opentable->uof[fd].addr = cur_opentable->uof[cur_opentable->cur_openfilesize - 1].addr; cur_opentable->cur_openfilesize--; cout direct[index].directname) { break; } } // 2 遍历当前目录下的文件 int i; for (i = 0; i < cur_user.next->direct[index].cur_file_size; i++) //判断当前目录下有没有这个文件 { if (cur_user.next->direct[index].ufd[i].filename == name) break; } if (i >= cur_user.next->direct[index].cur_file_size) { cout uof[j].filename == name) break; } if (j < cur_opentable->cur_openfilesize) //说明文件被打开了 { cout direct[index].ufd[i].filename = cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size - 1].filename; cur_user.next->direct[index].ufd[i].addr = cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size - 1].addr; cur_user.next->direct[index].ufd[i].length = cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size - 1].length; cur_user.next->direct[index].ufd[i].protect_code = cur_user.next->direct[index].ufd[cur_user.next->direct[index].cur_file_size - 1].protect_code; cur_user.next->direct[index].cur_file_size--; //用户文件数量减1 // 5 回收磁盘:更新文件分配表fat //cur_user.next->direct[index].ufd[i].addr 即 起始地址的块号(下标表示,所以从0开始) //temp 记录文件分配表下标 int temp = fat[cur_user.next->direct[index].ufd[i].addr].next; while (temp != -1) { fat[temp].used = 0; temp = fat[temp].next; } cout direct[index1].directname) { break; } } // 2 文件下标 int a; //遍历文件 for (a = 0; a < cur_user.next->direct[index1].cur_file_size; a++) //判断文件是否存在 { if (cur_user.next->direct[index1].ufd[a].filename == name) break; } if (a >= cur_user.next->direct[index1].cur_file_size) { cout uof[i].filename == name) break; } if (i >= cur_opentable->cur_openfilesize) { cout = cur_opentable->cur_openfilesize) { cout direct[index1].ufd[k].addr == first_block) { temp = k; break; } } //追加写 // 5 找到该文件存放的最后一个磁盘块 while (fat[first_block].next != -1) { first_block = fat[first_block].next; } //计算该文件存放的最后一个地址 char * first; first = fdisk + first_block * 512 + cur_opentable->uof[fd].pointer % 512; // 6 如果最后一个文件剩下的空间大于要写入的长度(不需要继续分配新的空闲块) if (len uof[fd].pointer % 512) { //strcpy(first, buf); 这句代码出现问题,可能是由于buf没有读满,后面的值被访问了,非法! for (int i = 0; i < len; i++) { first[i] = buf[i];//将缓冲区的内容写入虚拟磁盘中 } cur_opentable->uof[fd].pointer = cur_opentable->uof[fd].pointer + len; //更新文件打开表 cur_user.next->direct[index1].ufd[temp].length = cur_user.next->direct[index1].ufd[temp].length + len; //更新用户目录文件表 } else // 7 如果之前的半块磁盘剩下的空间不足写入 { // 7.1 写入一部分的内容到最后一个磁盘块的剩余空间 for (i = 0; i < 512 - cur_opentable->uof[fd].pointer % 512; i++) { first[i] = buf[i]; } // 7.2 计算分配完最后一个磁盘的剩余空间后,还剩下多少字节没有存储,计算还需要分配多少空闲块 int last_size = len - (512 - cur_opentable->uof[fd].pointer % 512); //剩余待写入的大小 int need_block_size = last_size / 512; //待分配的空闲块数 int need_offset_size = last_size % 512; //偏移量 if (need_offset_size > 0) need_block_size++; //总共需要这么磁盘块 // 7.3 判断磁盘剩余空间是否足够 int unused_block_size = 0; //记录没有使用过的磁盘块的个数 for (int i = 0; i < 64; i++) { if (fat[i].used == 0) { unused_block_size++; } } if (unused_block_size < need_block_size) { cout uof[fd].pointer = cur_opentable->uof[fd].pointer + last_size; //更新用户目录文件表 cur_user.next->direct[index1].ufd[temp].length = cur_user.next->direct[index1].ufd[temp].length + last_size; } } cout direct[index1].directname) { break; } } if (path == "") //表示此时路径在用户的目录表,显示文件目录 { cout direct[cur_user.next->cur_user_direct_size-1].cur_file_size; //注意这里需要减一,由于本身结构的限制 cur_user.next->direct[index].directname = cur_user.next->direct[cur_user.next->cur_user_direct_size-1].directname; for (int i = 0; i < cur_user.next->direct[cur_user.next->cur_user_direct_size-1].cur_file_size; i++) //注意这里的减一 { cur_user.next->direct[index].ufd[i].addr = cur_user.next->direct[cur_user.next->cur_user_direct_size-1].ufd[i].addr; cur_user.next->direct[index].ufd[i].filename = cur_user.next->direct[cur_user.next->cur_user_direct_size-1].ufd[i].filename; cur_user.next->direct[index].ufd[i].length = cur_user.next->direct[cur_user.next->cur_user_direct_size-1].ufd[i].length; cur_user.next->direct[index].ufd[i].protect_code = cur_user.next->direct[cur_user.next->cur_user_direct_size-1].ufd[i].protect_code; } cur_user.next->cur_user_direct_size--; //目录数量减1 cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3