操作系统实验报告.docx_第1页
操作系统实验报告.docx_第2页
操作系统实验报告.docx_第3页
操作系统实验报告.docx_第4页
操作系统实验报告.docx_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

操作系统课程设计实验报告院系:计算机科学与技术专业:计算机科学与技术班级: 姓名: 学号: 2012 年 03月 10 日一、 课程设计任务1.1课设目的 掌握Linux操作系统的使用方法; 了解Linux系统内核代码结构; 掌握实例操作系统的实现方法。 通过OS子系统的设计、增强OS设计的技巧,达到提高解决实际OS的设计能力的提高。1.2设计内容(1) 掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。 编一个C程序,其内容为实现文件拷贝的功能; 编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库。(2) 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,调用新增加的系统调用。 实现的功能是:文件拷贝;(3) 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。实现字符设备的驱动(4) 了解和掌握/proc文件系统的特点和使用方法 (选做)a) 了解/proc文件的特点和使用方法b) 监控系统状态,显示系统中若干部件使用情况c) 用图形界面实现系统监控状态。(5) 设计并实现一个模拟的文件系统(选做) 多用户的多级目录的文件系统设计。 多用户、多级目录、login (用户登录)、系统初始化(建文件卷、提供登录模块)、文件的创建、文件的打开、文件的读、文件的写、文件关闭、删除文件、创建目录(建立子目录)、改变当前目录、列出文件目录、退出二、 实验环境2.1 Linux系统版本可用版本 Fedora 5.0 6.0 ubuntu 10.04 11.10 内核版本linux-2.6.x 尽量使用2.6.32以前的内核版本本实验操作系统为:ubuntu 10.04内核版本号:Linux 3.0.24三、 实验内容3.1 Linux下的C编程实验原理先在父进程中利用fork( )函数创建一个子进程,再在子进程中创建一个子进程,然后在各个进程的运行过程中分别生成一个窗口,同时在相应的进程窗口中显示该进程的ID。生成窗口时可使用图形库GTK 2.0,在每个窗口中加入几个构件(button,progress bars,label等),并将每个构件所产生的动作与相应的信号处理函数相连接。Linux环境中,创建进程只需调用fork( )函数即可。进程调用fork后,系统会创建一个子进程,此子进程与父进程唯一不同的地方在于其进程ID与父进程ID:对于父进程,fork返回子进程的ID,对于子进程则返回0,系统就是通过此返回值的不同来区分父子进程的。若fork调用失败,则返回-1。GTK(GIMP Toolkit)是一个图形用户编程接口工具,本次实验将会用到的主要内容是控件、消息处理器和回调函数。利用控件可以实现一些图形的显示,比如显示窗口等等。消息处理器等待事件的发生(关闭窗口、点击按钮等),并捕获该信号,告诉GTK程序应该调用哪个回调函数进行相应的处理,并在终端中显示结果。详细内容请参见GTK 2.0教程(可从网上下载)。实验过程编译GTK程序与编译普通的C程序需要用到不同的命令。比如程序名为threeproc,则编译命令为:gcc pkg-config cflags -libs gtk+-2.0threeproc.c o threeproc ,注意 ,在不同的系统下,编译命令的参数顺序可能略有不同,如:gcc 1_2.c -o 1_2pkg-config -cflags -libs gtk+-2.0 在某次实验的时候,就不能通过编译,提示1_2.c:1:21: 错误:gtk/gtk.h:没有那个文件或目录但更换一下参数顺序就可以了:gcc pkg-config -cflags -libs gtk+-2.01_2.c -o 1_2该部分的运行结果如下: threeproc.c内容为:#include #include #include #include #include #include #include void main(int argc,char argv)pid_t p1,p2;pid_t t1,t2;int status;if(p1=fork()=0) /*创建第一个子进程*/execv(./proc,argv);else if(p2=fork()=0) /*创建第二个子进程*/execv(./clock,argv); elseexecv(./helloworld,argv); t1=waitpid(p1,&status,0);t2=waitpid(p2,&status,0);实验成功。3.2 系统调用简介:系统调用是应用程序和操作系统内核之间的功能接口,通过系统调用进程可由用户模式转入内核模式,在内核模式下完成相应的服务之后再返回到用户模式。系统调用的主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输出系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。实验原理Linux用来实现系统调用异常的实际指令是:int $0x80 这一指令使用中断/异常向量号128(即16进制的80)将控制权转移给内核(进行模式切换)。为达到在使用系统调用时不必用机器指令编程,在标准的C语言库中为每一系统调用提供了一段短的子程序,完成机器代码的编程工作。事实上,机器代码段非常简短。它所要做的工作只是将送给系统调用的参数加载到CPU寄存器中,接着执行int $0x80指令。然后运行系统调用,系统调用的返回值将送入CPU的一个寄存器中,标准的库子程序取得这一返回值,并将它送回用户程序。下面以getuid()系统调用为例来看调用过程:用户程序int main().getpid();标准C库int getuid(void)long _res;.int $0x80中断处理ENTRY(system_call)pushl %eaxSAVE_ALLGET_CURRENT(%ebx)call sys_getuid16RESTORE_ALLRESTORE_ALL内核例程asmlinkage longsys_getuid16(void)return hig2lowuid(current_uid);实验过程A.步骤1:下载源代码如果系统不包含源文件,则需要在网站上下载系统源代码网址: B.步骤2:修改相应内核文件(1) 修改(添加)源代码 第一个任务是编写加到内核中的源程序,即将要加到一个内核文件中去的一个函数,该函数的名称应该是新的系统调用名称前面加上sys_标志。假设新加的系统调用为mycall(int number),在/usr/src/linux3.0.24/kernel/sys.c文件中添加源代码,如下所示: asmlinkage int sys_mycall(int n,const char* sfile,const char* tfile)/* mycall文件拷贝 */int from_fd,to_fd; int bytes_read,bytes_write; char bufferBUFFER_SIZE;/* 设定一个缓冲区 */char *ptr; mm_segment_t old_fs;old_fs=get_fs(); /*保存原来的段*/set_fs(KERNEL_DS); /*设置为数据段*/if(n!=3)/* 三个参数 */ printk(KERN_ERR Usage:%s fromfile tofilena,sfile); return(-1); /* 打开源文件 */ if(from_fd=sys_open(sfile,O_RDONLY,S_IRUSR)=-1) printk(KERN_ERR Open %s Errorn,sfile); return(-1); /* 创建目的文件 */ if(to_fd=sys_open(tfile,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)=-1) printk(KERN_ERR Open %s Errorn,tfile); return(-1); /* 以下代码是一个经典的拷贝文件的代码 */ while(bytes_read=sys_read(from_fd,buffer,BUFFER_SIZE)/* 一个致命的错误发生了 */ if(bytes_read=-1) break; else if(bytes_read0) ptr=buffer; while(bytes_write=sys_write(to_fd,ptr,bytes_read)/* 一个致命错误发生了 */ if(bytes_write=-1)break; /* 写完了所有读的字节 */ else if(bytes_write=bytes_read) break; /* 只写了一部分,继续写 */ else if(bytes_write0) ptr+=bytes_write; bytes_read-=bytes_write; /* 写的时候发生的致命错误 */ if(bytes_write=-1)break; set_fs(old_fs);sys_close(from_fd); sys_close(to_fd); return(1); (2) 连接新的系统调用 添加新的系统调用后,下一个任务是使Linux内核的其余部分知道该程序的存在。为了从已有的内核程序中增加到新的函数的连接,需要编辑两个文件。entry.s文件中的sys_call_table独立出来,我们可以在该文件下看到类似于#includesyscall_table.s字样,说明我们正真需要修改syscall_table.s。 在syscall_table.s中有类似如下的清单:.long sys_name该清单用来对sys_call_table数组进行初始化。该数组包含指向内核中每个系统调用的指针。这样就在数组中增加了新的内核函数的指针。我们在清单上最后添加一行:.long sys_mycall /*新增系统调用337,文件拷贝*/第二个要修改的文件是unistd.h(一般情况下有两个unistd.h需要修改): /usr/src/linux8/include/asm-i386/unistd.h /usr/include/asm/unistd.h该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。文件中每一行的格式如下: #define _NR_name NNN其中,name用系统调用名称代替,而NNN则是该系统调用对应的号码。应该将新的系统调用名称加到清单的最后,按syscall_table.S文件的编号给它分配号码序列中下一个可用的系统调用号。我们的系统调用如下: #define _NR_rt_tgsigqueueinfo 240_SYSCALL(_NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)#define _NR_perf_event_open 241_SYSCALL(_NR_perf_event_open, sys_perf_event_open)#undef _NR_syscalls#define _NR_syscalls 242最后一行说明内核自身的系统调用号已经使用到241,共有242个(从0开始)。我们新添加的系统调用应该加到最后,并修改系统调用总数。修改如下:#define _NR_rt_tgsigqueueinfo 240_SYSCALL(_NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)#define _NR_perf_event_open 241_SYSCALL(_NR_perf_event_open, sys_perf_event_open)/* #undef _NR_syscalls */#define _NR_mycall 337/*新增系统调用-文件拷贝*/#undef _NR_syscalls#define _NR_syscalls 338必须注意添加的行的位置,否则容易造成内核编译的失败。C.步骤3:开始对新的内核进行编译先切换目录: cd /usr/src/linux-3.0.24/ 命令: sudo make mrproper sudo make menuconfig (第一次这步可能执行出错,需要安装什么包如下命令安装:sudo apt-get install libncurses5-dev,安装好后,再make menuconfig),为了避免选择的麻烦,直接按下键一直到最下面,选中 save-回车就可以了,退出到终端。 sudo make 简单的命令(此步由make bzImage 和 make modules两步组成,两步操作都要等很长时间,还不如等一步,之后就是让机子慢慢的编译内核去了)sudo make modules_installsudo make installsudo update-grub 编译好了,可以直接重启计算机了,可以看到开机启动项里多了linux-3.0.24的选项,选择进入此系统说明:其中make mrproper命令用来清除旧的配置等文件,避免编译内核时生成的文件不一致;make xconfig用于选择内核编译配置,事实上还有config,gconfig,menuconfig等选项可以选用。如果执行成功,则在/boot/grub中的grub.conf中会出现新内核的选项。至此,新内核已经建立,新添加的系统调用已经成为操作系统的一部分,重启后选用新内核即可测试该新的系统调用。(3)对新加的系统调用进行测试#include#include#include#includeint main(int argc,char *argv)int b=syscall(337,argc,argv1,argv2); /*第一个参数系统调用号,之后的根据系统调用参数*/printf(%dn,b);return 0;在当前路径下编译执行该程序。运行结果:#gcc o mysyscall_copy mysyscall_copy.c#./mysyscall_copy1#uname r3.0.24可见,在新内核下测试成功。3.3. 增加设备驱动程序实验原理系统调用是操作系统内核和应用程序之间的接口,而设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:(1) 对设备初始化和释放. (2) 把数据从内核传送到硬件和从硬件读取数据. (3) 读取应用程序传送给设备文件的数据和回送应用程序请求的数据. (4) 检测和处理设备出现的错误. 设备驱动程序工作的基本原理:用户进程利用系统调用对设备进行诸如read/write操作,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。最后,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度.也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,你只有重新启动机器了。实验过程A.写设备驱动源代码:在设备驱动程序中有一个非常重要的结构file_operations,该结构的每个域都对应着一个系统调用。struct file_operations int (*seek) (struct inode * ,struct file *, off_t ,int); int (*read) (struct inode * ,struct file *, char ,int); int (*write) (struct inode * ,struct file *, off_t ,int); int (*readdir) (struct inode * ,struct file *, struct dirent * ,int); int (*select) (struct inode * ,struct file *, int ,select_table *); int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long); int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *); int (*open) (struct inode * ,struct file *); int (*release) (struct inode * ,struct file *); int (*fsync) (struct inode * ,struct file *); int (*fasync) (struct inode * ,struct file *,int); int (*check_media_change) (struct inode * ,struct file *); int (*revalidate) (dev_t dev); 编写设备驱动程序的主要工作是编写子函数,并填充file_operations的各个域。例如: Struct file_operations my_fops= .read=my_read, .write=my_write, .open=my_open, .release=my_release然后再定义函数my_read,my_write,my_open,my_release相应的函数体。例如:static ssize_t my_open(struct inode *inode,struct file *file)static int counter=0;if(Device_Open)return -EBUSY; Device_Open+; /*写入设备的信息*/sprintf(msg,the device has been called %d timesn,counter+); msg_ptr=msg;return 0;同时对于可卸载的内核模块(LKM),至少还有两个基本的模块:例如本例中的:static int _init my_init(void)int result;result=register_chrdev(0,sky_driver,&my_fops);if(result0)printk(error:can not register the devicen);return -1; if(my_major=0) my_major=result;printk(hehe,the device has been registered!n);printk(the virtual device was assigned major number %d.n,my_major);printk(To talk to the driver,create a dev file withn);printk(mknod/dev/my c %d 0n,my_major);printk(Remove the dev and the file when donen); return 0;static void _exit my_exit(void) unregister_chrdev(my_major,sky_driver);printk(unloading the devicen);my_init 用于注册设备,获得设备的主设备号调用register_chrdev(0,“sky_driver(设备名)”,&my_fops);my_exit 用于注销设备调用unregister_chrdev(my_major, “sky_driver(设备名)”);然后在程序尾再调用这两个函数 Module_init(my_init); Module_exit(my_exit) MODULE_LICENSE(“GPL”);B.编译(1) 新建设备驱动源文件:mydriver.c(2) 写Makefile文件ifneq ($(KERNELRELEASE),) #kbuild syntax.#模块的文件组成mymodule-objs :=mydriver.o #生成的模块文件名obj-m := mydriver.o elsePWD :=$(shell pwd)KVER :=$(shell uname -r)KDIR :=/lib/modules/$(KVER)/buildall:$(MAKE) -C $(KDIR) M=$(PWD)clean:#rm -f *.cmd *.o *.mod *.korm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions#$(MAKE) -C $(KDIR) M=$(PWD) cleanendif(3) 编译在当前路径下执行make如果编译成功将得到.ko文件注意:此步编译过程中必须没有错误或者任何的警告,否则必须对错误和警告信息提示的位置进行修改,然后重新编译,直到没有任何错误或者警告(warning)为止。C.挂载内核中模块命令:insmod ./mydriver.ko此时 cat /proc/devices或dmesg会看到在字符设备中有250mydriver。前面的是系统分配的主设备号,后面是设备注册名。D.创建新的虚拟设备文件命令:mknod /dev/mydriver C 250 0在此命令中,第一个参数是新建设备文件的地址和名字,第二个参数是指创建的是字符设备文件,第三个参数是主设备号,第四个参数是从设备号。执行成功会在/dev中看到一个新的设备文件mydriver.E.测试新的设备驱动编写测试程序test.c: #include #include #include #include #include int main(void) int fd; char buf1024; char get1024; memset(get, 0, sizeof(get); memset(buf, 0, sizeof(buf); printf(please enter a string you want input to mydriver:n); gets(get); fd = open(/dev/mydriver, O_RDWR, S_IRUSR|S_IWUSR);/打开设备if (fd 0) read(fd, &buf, sizeof(buf); printf(The message in mydriver now is: %sn, buf); /将输入写入设备write(fd, &get, sizeof(get); /读出设备的信息并打印read(fd, &buf, sizeof(buf); printf(The message changed to: %sn, buf); sleep(1); else printf(Wrong!); return -1; close(fd);/释放设备return 0; 运行结果:#gcc o test test.c#./testWrite a string in the driver:Bcd!Now the mydrivers string is: abc!The string is changed to : Bcd!F.卸载操作删除模块命令:rmmod sky_driver删除新增的字符设备文件命令:rm /dev/sky_driver3.5. 模拟文件系统(1)实验目的通过OS子系统的设计、增强OS设计的技巧,达到提高解决实际OS的设计能力的提高。(2)实验内容多用户的多级目录的文件系统设计。(3)实验要求1)多用户 :usr1,usr2,usr3,usr8 (1-8个用户)2)多级目录:可有多级子目录;3)具有login (用户登录)4)系统初始化(建文件卷、提供登录模块)5)文件的创建: create (用命令行来实现)6)文件的打开:open7)文件的读:read8)文件的写:write9)文件关闭:close10)删除文件:delete11)创建目录(建立子目录):mkdir12)改变当前目录:cd13)列出文件目录:dir14)退出:logout(4)提示1)设计手段 创建一个1M 磁盘空间的文件来作为文件系统的空间;2)文件卷的组织:将文件卷分块、用位示图来管理;块的大小可设成512字节,块数为512块,可用第0#块作为管理块,1#块作为位示图;3)系统结构(a) 块管理层: 分块分配、块回收、块读、块写等(b) 文件控制块层(FCB) 目录查找namei(),iget(),iput()(c) 文件管理层 具有打开文件 open( ),close( )等;(d) 命令解释层4)数据结构(a) 目录结构(b) FCB结构(c) 打开文件结构(d) 用户结构开始(5)总体的设计思路(程序的流程):登陆模块命令解释执行模块(6)运行结果:用户登录:当首次启动文件系统的时候,如果user.dat中没有用户,则会提示是否创建用户,如下所示登陆成功后可以查看根目录的文件如下所示:现在演示创建文件,打开,读写等文件操作,创建文件txt创建成功如下所示:打开文件:以读写方式写文件:写成功后如下所示:读文件删除文件,结果提示如下:显示多级目录结构如下图,一次嵌套创建 a b c 并使用cd:其中创建的各个目录的状态:四、 课程设计总结4.1课设总结操作系统原理是计算机专业的核心专业基础课。课程设计属于设计型实验,不仅锻炼学生简单操作能力,而且通过进行设计及实现,进一步提高分析和解决问题的能力。操作系统课程设计的总体目标是掌握Linux操作系统的使用方法。通过Linux下编程,编译Linux内核增加系统调用,为Linux添加新的系统调用以及小型文件系统的设计与实现这些递增性的实验操作,让我们更好的学会Linux操作系统的使用方法。本次课程设计任务相对比较繁重,我的方案是先解决文件系统,然后再在linux下操作前三个实验。通体来说,模拟实现了UNIX文件系统,较好地实现了课程设计的任务和要求及各个功能。本系统的功能较完善,实现了文件系统的初始建立,格式化操作,用户的切换,用户权限管理,删除目录树等新增加的功能(改进),完整地实现了课程设计所要求的基本功能:新建用户、文件、目录,删除文件、目录,进入、退出目录,文件的打开、读、写、关闭等。 而其他三个实验就没有那么多时间去操作了,尤其是第三个,在我写完文件系统之后就没有时间,最后在网上找了点资料草草收尾。虽说后来有所加工,但还是有所遗憾。4.2课设体会这次课程设计收获颇大,主要有两个方面:对linux系统以及对其的操作有了一定深入的了解主要也是对linux内核的编程,linux环境下的命令行的操作有了极大的熟悉和理解。实验应该说比较具有代表性,是一个很好的 linux环境下编程的例子.也让我从中学到了不少 linux的知识. 总之,我已经对linux产生了浓厚的兴趣。模拟实现的文件系统这个项目也让我影响深刻,通过课程设计,进一步融会贯通教材内容,理解了的文件系统的结构,掌握程序各功能模块的工作原理,相互联系和来龙去脉,完整地建立系统的概念。同时,这个文件系统的实验也激发我的学习热情和主动性,在实践活动中,将所学知识综合运用,增长才干,并积累经验。这次文件系统的实验让我有进一步熟悉的语言的编程,同时也熟悉在的集成开发,感受良多。最后,要感谢阳老师的指导,帮助我顺利实现操作系统的课程设计。附:文件系统源代码头文件 #include #include #include #include #define BLOCKSIZE 512 /块的大小#define BLOCKNUM 512 /块的个数#define INODESIZE 32 /i节点的大小#define INODENUM 32 /i节点的个数#define FILENUM 8 /用户typedef struct char username10; char pwd10; User; /i节点typedef struct short i; char filename10; char username10; char type; short parent; short length; short block2; Inode; /打开文件表typedef struct char filename10;short inum; short mode; short offset; File_table; void help(void); void cd(void); void dir(void); void mkdir(void); void creat(void); void open(void); void read(void); void write(void); void close(void); void del(void); void logout(void); void command(void); void rd(void); void quit(void); void free_user(void);void errcmd(void);void format(void);void login(void); void init(void); int analyse(char *); void save_inode(int); int get_blknum(void); void read_blk(int); void write_blk(int); void release_blk(int); void pathset(void); void delet(int innum); int check(int i); 源程序#include h.hchar choice;int argc;char *argv5; int inum_cur; char temp2*BLKSIZE; User user; / char bitmapBLKNUM;Inode inode_arrayINODENUM; File_table file_arrayFILENUM;char image_name10 = FILE *fp; void format(void)FILE *fp;int i;Inode inode;printf(Will be to format filesystem.n);printf(WARNING:ALL DATA ON THIS FILESYSTEM WILL BE LOST!n);printf(Proceed with Format(Y/N)?);scanf(%c, &choice);gets(temp);if(choice = y) | (choice = Y)if(fp=fopen(image_name, w+b) = NULL) printf(Cant create file %sn, image_name);exit(-1);for(i = 0; i BLKSIZE; i+)fputc(0, fp);inode.inum = 0;strcpy(inode.file_name, /);inode.type = d;strcpy(inode.user_name, all);inode.iparent = 0;inode.length = 0;inode.address0 = -1;inode.address1 = -1;fwrite(&inode, sizeof(Inode), 1, fp);inode.inum = -1;for(i = 0; i 31; i+)fwrite(&inode, sizeof(Inode), 1, fp);for(i = 0; i BLKNUM*BLKSIZE; i+)fputc(0, fp);fclose(fp); / 打开a文?件tuser.txtif(fp=fopen(user.txt, w+) = NULL)printf(Cant create file %sn, user.txt);exit(-1);fclose(fp);printf(Filesystem created successful.Please first login!n);return ;void login(void)char *p = NULL;int flag;char user_name10;char password10;char file_name10 = user.txt;p = password;doprintf(login:);gets(user_name);printf(password:);while(*p=getch()if(*p = 0x0d) /当输?入?回?车键时,?0x0d为a回?车键的?ASCII码?*p=0; /将?输?入?的?回?车键转a换?成空?格?break;printf(*); /将?输?入?的?密码?以?*号?显?示?p+;flag = 0;if(fp = fopen(file_name, r+) = NULL)printf(nCant open file %s.n, file_name);printf(This filesystem not exist, it will be create!n);format();login();while(!feof(fp)fread(&user, sizeof(User), 1, fp);/ 已?经-存?在的?用?户, 且密码?正y确 if(!strcmp(user.user_name, user_name) & !strcmp(user.password, password)fclose(fp);printf(n);return ;else if(!strcmp(user.user_name, user_name)printf(nThis user is exist, but password is incorrect.n);flag = 1;fclose(fp);break;if(flag = 0)break;while(flag);/ 创建新?用?户 if(flag = 0)printf(nDo you want to creat a new user?(y/n):);scanf(%c, &c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论