用C语言编写一个教室教室借用管理系统统

豆丁微信公众号
君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
教师信息管理系统(C语言课程设计)教师信息管理
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
教师信息管理系统(C语言课程设计)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口如何从零开始写一个简单的操作系统? - 知乎<strong class="NumberBoard-itemValue" title="被浏览<strong class="NumberBoard-itemValue" title="1,625分享邀请回答ilovecl.com//os_redleaf/ )(一)OS说明今后,我就要开始折腾操作系统,有了一点小小干劲。我的计划是,先看过一份用于教育目的的系统源码,再去翻找相应的资料(我手头已有绿宝书),在翻资料的同时开始写代码,然后做好移植真机的工作,DONE! 我也明白,理性很丰满,现实很骨感,这过程不会如同我计划中这般简单和轻松。但是,见难而退可不是我的风格(那样我会被红叶二小姐调戏的),不管如何,我都会,怎么说呢,尽力吧。出于课程需求,斯坦福那些人亲自写了一个名为“pintos”的系统。pintos的结构比较简单,分为进程管理、文件系统、用户程序、虚拟内存等几个部分,也正是因为这个原因,我选择pintos作为我的参考蓝本,现在在读它的源码。在接下来的几个月时间里,不出意外的话,我会不断的在博客上更新我的进度。(三)交叉编译环境倘若我们要在ubuntu上编译另外一个完整的OS,交叉编译环境是必不可少的玩意,维基百科有云:交叉编译器(英语:Cross compiler)是指一个在某个系统平台下可以产生另一个系统平台的可执行文件的编译器。 (想起以前,我为了给路由器编译OPENWRT,下载大量源码,愣是编译了几天几夜。那时候的我,真是“可爱”。) 为了配置好交叉编译环境,我废了好大力气,最后勉强找到了组织。 编译环境大致分为2部分,binutils和gcc。我先装好gcc-4.9.1,之后下载gcc-4.9.1和binutils-2.25的源代码,似乎gcc版本与binutils版本要对应来着…开始编译之前,需要准备全局变量(在命令行中敲入以下命令):export PREFIX=”$HOME/opt/cross” export TARGET=i686-elf export PATH=”$PREFIX/bin:$PATH” 编译Binutils cd $HOME/binutils-2.25 mkdir build-binutils cd build-binutils #注意是在源码目录下面新建一个文件夹,然后cd到该文件夹里,然后才配置configure,不这么做的话,嘿嘿.. ../binutils-x.y.z/configure –target=$TARGET –prefix=”$PREFIX” –with-sysroot –disable-nls –disable-werror make make install –disable-nls 告诉binutils,不要添加本地语言支持–with-sysroot 告诉binutils,在交叉编译器中允许sysroot编译GCC cd $HOME/gcc-4.9.1 mkdir build-gcc cd build-gcc #注意是在源码目录下面新建一个文件夹,然后cd到该文件夹里,然后才配置configure,不这么做的话,嘿嘿.. ../gcc-x.y.z/configure –target=$TARGET –prefix=”$PREFIX” –disable-nls –enable-languages=c,c++ –without-headers make all-gcc make all-target-libgcc make install-gcc make install-target-libgcc –disable-nls 告诉GCC,不要添加本地语言支持。–without-headers 告诉GCC,不要依赖任何本地库,我们必须在自己的OS中实现库。–enable-languages 告诉GCC,不要支持除了C、C++之外的语言。提醒 不同机器配置不同,编译速度也不同。编译这两个软件,我花了近3个钟,机器配置之低自不必说,说了都是泪。如果任何人的任何编译过程出了任何问题,请仔细地、认真地、用心地再看看上面的命令,在你没有弄懂它的原理之前,请不要擅自做任何“改进”(血淋淋、赤裸裸的教训呀)。(五)OS模糊框架翻完了手头的绿宝书,我才晓得,人都是被逼出来的。操作系统的概念都差不多已经知道,接下来,该由“理论态”切换到“实践态”了喔(书还是不能看太多,会中毒的–)。对了,从别人推荐的地方弄来了一个框架(曾在android平台写了几万代码,我深深体会到框架的作用),轻松开工吧。先说明一下这个框架:Meaty Skeleton,开源示例,内核和用户分离,方便扩展,嗯,没了。最近烦杂事情很多,心情,不算愉快也不算低落吧,近来又梦见红叶,不知道又要发生什么,不管。(六)内核第一步任务:GDT完成天色已晚,又下着雨,我也忘记带伞了,嗯,等会儿再回去好了,这个商城的环境还是蛮好的。今天实现了GDT。(也不算是实现吧,因为我打算使用纯分页的流氓招数,放弃纯分段或分段分页混合,所以就不太用心于实现GDT,只是浏览INTEL的官网,借用了几个FLAG定义之类的东西,匆匆就写完了GDT)下面是记忆:使用内嵌式汇编 分4个段,两个高级的内核分段,两个低级id用户分段 预留了一个TSS,虽然也不打算用硬件实现任务切换(听前辈们说,硬件实现非常的麻烦) 把 设置GDT表的函数(init_gdt)放在kernel/arch/i386/global_descriptor_table.c中,而段 segment_descriptor的定义(seg_desc)则放在kernel/include/kernel /global_descriptor_table.h 引用了英特尔的一份公开资料 一些全局或者说全世界通用的参数放在kernel/include/kernel/global_parameter.h,有些人更绝,把所有函数的原型放在一个地方,哪怕内核级函数和用户级函数混在一起 翻了太多资料,头都晕了 按进度来看,有点紧,也无妨。(七)内核第二步任务:IDT完成佛说人者,非人者,名人者。 已经写好IDT的载入,加上之前的GDT载入,就已经完成两个与机器硬件相关的模块(准确的说,应该是给CPU的特定单元载入内容)。不过我并没传说高手那么厉害,高手们一天一个模块,可我近几天连IDT对应的IRC和HANDLE都还没弄。在bochs上调试时,分别 键入info gdt 和info idt 1,能看到GDT和IDT的内容。今日要点:AT&T汇编和寻常的INTEL有些许区别,不过区别不是很大 GDT和IDT都是固定的表,必须实现,实现方法各异 之前留下的TSS并非用于切换任务,而是用于保存从“用户态”回到“内核态”时必须使用的跳转地址 未完待续 后记,IDT里面的OFFSET并没有得到正确的值,因为IRQ还没设置好,相应的HANDLE还没有弄好 日01:14:25补充:设 置了IDT表中的头32个项,也就是ISR(interrupt service routines),它专门处理诸如“除以0”/“Page Fault”/“Double Fault”等exception,它对exception的处理方式也很简单,或者说根本没有处理,仅仅是打印exception的类型而已。我 随便写了一句int a = 1/0,调试的时候,bochs提示”write_virtual_checks(): no write access to seg”。可能是内核还没具有从用户态跳转到内核态的能力吧,毕竟IDT的头32个项都拥有ring0的级别,明天再看看。补上3种中断类型:Exception: These are generated internally by the CPU and used to alert the running kernel of an event or situation which requires its attention. On x86 CPUs, these include exception conditions such as Double Fault, Page Fault, General Protection Fault, etc.Interrupt Request (IRQ) or Hardware Interrupt: This type of interrupt is generated externally by the chipset, and it is signalled by latching onto the #INTR pin or equivalent signal of the CPU in question. There are two types of IRQs in common use today.IRQ Lines, or Pin-based IRQs: These are typically statically routed on the chipset. Wires or lines run from the devices on the chipset to an IRQ controller which serializes the interrupt requests sent by devices, sending them to the CPU one by one to prevent races. In many cases, an IRQ Controller will send multiple IRQs to the CPU at once, based on the priority of the device. An example of a very well known IRQ Controller is the Intel 8259 controller chain, which is present on all IBM-PC compatible chipsets, chaining two controllers together, each providing 8 input pins for a total of 16 usable IRQ signalling pins on the legacy IBM-PC. Message Based Interrupts: These are signalled by writing a value to a memory location reserved for information about the interrupting device, the interrupt itself, and the vectoring information. The device is assigned a location to which it wites either by firmware or by the kernel software. Then, an IRQ is generated by the device using an arbitration protocol specific to the device’s bus. An example of a bus which provides message based interrupt functionality is the PCI Bus.Software Interrupt: This is an interrupt signalled by software running on a CPU to indicate that it needs the kernel’s attention. These types of interrupts are generally used forSystem Calls. On x86 CPUs, the instruction which is used to initiate a software interrupt is the “INT” instruction. Since the x86 CPU can use any of the 256 available interrupt vectors for software interrupts, kernels generally choose one. For example, many contemporary unixes use vector 0x80 on the x86 based platforms. 今天载入到IDT中的,正是第一种类型(Exception),只不过换了个名字叫ISR而已。未完待续。日12:06:45补充:之前的”write_virtual_checks(): no write access to seg”错误并不是权限的问题,而是段寄存器DS的值错误,它的值应该是0x10,可我给它赋值0x08。0x08是段寄存器CS的值,0x10才是段寄存器DS的值。另外,这at&t汇编里面,把C语言函数的地址赋给寄存器,必须在函数名前面加上$。至此,ISR彻底完成,只是,似乎IRQ又出了点问题….未完待续。(十)内核第三步任务:分页完成稍微做下记录…得到内存大小 首先,利用grab得到物理内存的实际大小。物理内存管理 然后,用一个数组map来监督物理内存,数组的每一项都对应着一个4K的物理内存。在这里我遇到了一个问题:数组的大小如何设置?因为还没有内存分配功能,所以不可能allocate一块或new一块内存来存放数组。找来找去也没找到合适的方案,就自己弄一个粗鲁一点儿的:设置数组大小为1024
1024。这样一来,数组的每一项对应4K,有1024
1024项,恰好可以对应4G大小的物理内存。但这样又有一个缺陷,倘若物理内存没有4G而是128M,那么该数组就有大部分元素被废弃了。现在先,额,不管这个,之后再解决。至于这物理内存它的实际分配,我是这么觉得的:把前64M的物理内存当作内核专属(把内核的所有内容全都加载到此处),剩余的物理内存才是空闲内存,用于allocate。为了方便分配物理内存,我采取最最最简单的方法:把所有空闲的物理页放到一条链里,需要的时候直接拿出来就可以了。虚拟内存管理 之后,就是把page_directory地址放入CR3并开启硬件分页功能了。page_directory,page_table等作用于虚拟地址。对于这4G的虚拟地址空间,排在前面大小为MEM_UPPER的一大块虚拟内存都是内核空间,剩下的排在后面的都是用户空间。也就是说,在有512M的物理的情况下,虚拟内存的前512M是内核态,后面的3584M是用户态。分页错误 内存分配的过程中,可能出现“页面不存在”、“页面只读”及“权限不足”3种错误。处理分页错误,CPU会自动调用14号ISRS,我们要做的,是把我们写的处理函数地址放到14号ISRS的函数栏即可。每次分页错误,CUP调用14号ISRS,继而跳入我们设计好的处理函数(-_-陷阱?)。不过我现在也是暂时先不写分页错误的处理函数,如果内存真的任性真的出错了,我也不会管它的,傲娇就傲娇吧。到这里,分页就算是初步完成了。致命的伤痛 很遗憾,物理内存设置好了,虚拟内存设置好了,也正常工作了,但是我一旦开启硬件的分页功能,就有”physical address not available”的错误,直接重启了,到底是怎么回事…再看看吧…未完待续。日12:54:14补充:bochs的”physical address not available”提示是这么个回事,把一个内容不对的分页目录加载进硬件(也就是把分页目录地址置入CR3)。在初始化分页目录时,我直接用了4M大页的方式初始化,但弄错了byte和KB的数量级,所以就出了一点小小的问题。遗留:page fault函数,待日后再写。写内存分配去吧!未完待续。(十一)内核第四步任务:内存分配完成内存分配?这可是个麻烦的活,不过,如果你足够聪明的话,就没什么问题了。 ——前人 上 一次,我准备好了分页的相关内容,比如说,载入分页目录/开启硬件支持/划分物理内存/划分虚拟内存等等。这一次,不会怂,就是干(为写内存分配模块而奋 斗,高扛自由的鲜红旗帜,勇敢地向前冲….)。分页准备好之后,下一步是如何地分配内存,比如,如何分配一页空白的可用的物理内存?如何分配一块空白 的虚拟内存?如何连续地分配等等等等。 第一节:申请和释放空白物理内存 申请物理内存,在分页的机制下,就是申请一页或连续几页空白的物理内存,释放则反过来。在 分页的时候,我已经将所有的空白物理页都放进了一个链表之中,现在要申请一个空白物理页,从链表中拿出来即可,太简单了。释放空白物理页,将物理页重新放 进链表里即可,也是非常的简单,有点简单过头了。当然啦,简单有省时省力的优点,同时,也有“无法同时分配许多页/分配大内存时(比如数十M)很吃力”的 缺点。这,按我的习惯,先留着,以后再说,现在能简单就简单。写好allocate_page和free_page两个函数之后,分配空白页倒是正常,但是内核出现”double fault”的错误,也就是8号ISR被CPU调用了,具体为甚,现在还不清楚,待我瞧瞧再说。未完待续。查资料如下:Normally, when the processor detects an exception while trying to invoke the handler for a prior exception, the two exceptions can be handled serially. If, however, the processor cannot handle them serially, it signals the double-fault exception instead. To determine when two faults are to be signalled as a double fault, the 80386 divides the exceptions into three classes: benign exceptions, contributory exceptions, and page faults. Table 9-3 shows this classification.Table 9-4 shows which combinations of exceptions cause a double fault and which do not.The processor always pushes an error code onto the stack of the double- however, the error code is always zero. The faulting instruction may not be restarted. If any other exception occurs while attempting to invoke the double-fault handler, the processor shuts down.————————————————————————–Table 9-3. Double-Fault Detection Classes Class ID Description1 Debug exceptions 2 NMI 3 Breakpoint Benign 4 Overflow Exceptions 5 Bounds check 6 Invalid opcode 7 Coprocessor not available 16 Coprocessor error0 Divide error 9 Coprocessor Segment Overrun Contributory 10 Invalid TSS Exceptions 11 Segment not present 12 Stack exception 13 General protectionPage Faults 14 Page fault ————————————————————————–Table 9-4. Double-Fault Definition SECOND EXCEPTIONBenign Contributory Page Exception Exception Fault Benign OK OK OK ExceptionFIRST Contributory OK DOUBLE OK EXCEPTION ExceptionPage Fault OK DOUBLE DOUBLE ————————————————————————–大概意思是:同时出现了2个中断,CPU不知道该处理哪个先,就是这样,就是如此的简单。之前没有这个错误,但分配和释放几个物理页之后就有这个问题,我估摸着两个都是Page fault,再看看吧。 刚刚调试了一下,我发现不是分配和释放几个物理页的问题,而是cli()和sti()的成对出现,去掉它们就没这个问题;更奇怪的是,就算只有sti() 允许中断出现,也会double fault,莫非我这前面关了中断或者是前面遇到了不可解决的中断遗留到现在?难道,是irq的重定位有问题?到底是为什么呢?先算入历史遗留问题吧,还 有重要的模块要完成。 (事情有点麻烦了呢?并不是内存分配这里出了问题,而是sti()惹的祸,不管这哪个位置,只要调用sti()开启中断,就会double fault,看来必须解决这个问题才行,我不可能一直不开中断吧…-_-) 睡了一觉,起来查资料,看到了关键的一句:make sure you didn’t forget the CPU-pushed error code (for exceptions 8,10 and 14 at least)到了,我翻出代码一看,哎呀嘛,我只注意到了8号软中断,没注意到10号和14号软中断(14号处理page fault),删去两行代码后,顺利开启中断! 未完待续。 第二节:分配内存(malloc/free) 既然已经可以正常地分配和释放物理内存页,那么在这一小节之中,很自然地,我的任务就是分配内存了。所谓“天将降大任于斯人也,必先让他实现一个内存分配的算法”,不外乎就是说,要实现void malloc(int size)和int free(void p, int num_page)两个大众情人函数。它 的大概思路就是这样的:先初始化一个桶,把可用的内存块都塞进去,要分配内存时,直接从桶里面找,找到了当然万事大吉大家都开心,如果找不到,就调用上面 那个申请空白的物理内存页的函数,弄一个4K物理内存页过来,将这个内存页分割成小块,丢到桶里面,然后继续找,就是这样…. 日23:19:08补充:遇到一个bug:每次申请的时候,可以正常申请,但是一旦使用了申请的内存,内核就报”page fault”的错误。想来想去,看来看去,最终发现,我在初始化分页机制的时候出了点小小的问题。秘技解决:初 始化虚拟内存时,我将大小和物理内存一样大(比如129920K)的虚拟内存设为内核级别并可用,剩下3个多G的虚拟内存是用户级别但不可用,我使用4M 大页载入分页表,所以我实际上载入了6 = 31个大小为4M可用的内核级别虚拟内存页,也就是说,在虚拟内存这个空间里,仅仅有31
4096 = 126976K的可用空间,其它的虚拟内存均是不可用的非法的;而在初始化物理内存时,我将前64M留给内核,后面的物理内存用于malloc和 free,比如有129920K,我把它划分为129920 / 4 = 32480个4K大小的物理内存页,也就是说,在物理内存这个空间里,仅仅有32480
4 = 129920K的可用空间,其它的物理内存均不在管理范围之内;这样一来,就出大问题了。假设我们要申请一个物理页,由于使用链的方式管理物理页,申请到的就是排在后面的物理内存,比如申请到了129916K到129920K这一个物理内存页,现在,我们要使用它,会发生什么呢?page fault!!!!!!!为 什么?很明显,在虚拟内存的空间里,最大的有效内存是126976K,CPU的分页表里只能找到前126976K,现在让CPU去找129916K,它根 本就找不到!它以为这个虚拟地址并没有对应这物理地址,是个错误!(附上page fault的引发条件:A page fault exception is caused when a process is seeking to access an area of virtual memory that is not mapped to any physical memory, when a write is attempted on a read-only page, when accessing a PTE or PDE with the reserved bit or when permissions are inadequate.) 于是我稍作改正,就正常了,可以正常使用申请到的内存-_-。未完待续。(十二)内核第五步任务:系统时钟中断、键盘中断我现在的状态不是很好,刚弄好系统时钟中断,每10ms发出一个中断请求;但键盘中断并没有弄好,没有识别键盘的按键SCANCODE,所以暂时只能识别第一次按键,系统收不到第二次按键中断,明个儿我再来看看,已经很晚了--!! 未完待续。日 15:51:00补充:查了一番资料,调试了一番,现在,键盘中断正常工作了,键盘可以正常工作,每输入一个字符,就在屏幕上显示出来。嗯哼,可以进入到进程模块了。(十三)内核第六步任务:进程创建在自习室里,我突然想到一个问题:一个进程,如何去创建它?(虽然之前翻完了大宝书,但毕竟一个多月都过去了,忘了具体的实现-_-)翻 翻书,找到一个和我的设想相差不多的方案:用一个特定的结构体代表一个进程,结构体中包含进程的相关信息,比如说进程的pid、上下文、已打开的文件、优 先级、已经占用的CPU时间、已经等待的时间、虚拟内存空间、错误码等等,创建进程的时候,只需要跳转到进程的虚拟内存空间即可。至于如何跳转,那就是内 核态的事情了,一般的进程都处在用户态,也就不必关心太多。如此,我们便是可以创建并运行一个进程了(不考虑文件系统),既然可以创建进程,可以切换进程,那么进程调度就很容易了,不过就是个复杂的进程切换过程而已,下一节便是写进程的调度罢。(十四)内核第七步任务:进程切换与进程调度黄粱一梦。 看到这句古语,顿时感慨万千,没想到仅仅数周时间,我的人生竟发生了这么大的转折(不是一夜暴富),仿佛一夜醒来,到另外一个平行世界里去。甚至,在睡梦中我都会惊醒。逝 者已逝,再多的话语也没用。只是,我不甘愿就这么结束而已。她也曾经说过:“此身不得自由,又何谈放纵”,现在我竟是极度赞同了。曾经想过在割腕的那一瞬 间,她的脑海里究竟有什么,有没有浮光掠影,有没有回放这一生的片段?如此年轻的生命,选择自我了断,需要多少黑暗沉淀,多少的落寞与失望…似乎一下 子也看开了。(以上只是个人情感的流露,忍不住必须得写些什么,请忽略)简单记录一下吧,没什么心情。进程切换时,只需要切换进程上下文,把context刷新一遍即可。至于进程调度,这个就简单许多了(其实也挺复杂),在时钟中断到来的时候,调整各个进程的优先级,并切换到相应的进程,就是这么简单。嗯,就这样吧,现在只想戴上耳机听听音乐….1.2K101 条评论分享收藏感谢收起65548 条评论分享收藏感谢收起用C语言编写一个学生管理系统。_百度知道
用C语言编写一个学生管理系统。
1、总体要求:系统功能齐全,运行结果正确,用户界面友好,使用简单方便。
2、系统数据要求:学生信息如下:学号、姓名、年龄、所在系、3门课程名称及成绩、总分、平均分。
3、系统功能要求:
⑴输入至少10个学生的自然信息(学号、姓...
我有更好的答案
高二的时候,我自己写过。现在在学其它的语言,就不献丑了,在网上给你找到了,是百度文库里面的,直接复制过来的话,排版不对,你自己去看一下吧,完整的代码。 名字就是《用C语言编写的一个学生信息管理系统》PS:写这个,主要是用到C语言的链表,不难,只是有的时候,如果思路不清晰的话,容易写错,写漏等等,如果不参考上面,而是你自己写的话,建议先画个大概的树图出来,再开始编吧。 纯手工打的,帮到你的话,就采纳吧。
那个jiemian(); 是什么意思啊?那个程序有的地方我还是有点不会改。。。
是一个自定义的调用函数。调用函数在C中可是很重要的噢!遇到不懂的慢慢找书上的知道识看看,你会收益不少的!
可以加你吗?有些问题想问问你。
不好意思噢,朋友,我已经有些年没怎么碰C啦,现在在学其它语言。我只能向你提供一下学习的方法而已。
采纳率:49%
我有一个功能基本上和这差不多。我贴给你吧。#include&stdio.h&#include&stdlib.h&#include&string.h&#include&ctype.h&#include&conio.h& struct
student { char name[21];
char number[21]; char specialty[21]; char sex[3]; int c_ int english_ int math_ int total_};typedef ststudent studentArray[100];char putout[9][21]={&姓名&,&学号&,&专业&,&性别&,&c语言&,&英语&,&数学&,&总成绩&,&名次&};
//为格式化输出做准备int count=0;
//用来记录学生的记录个数//函数声明部分void initialStudent();void addStudent();int judge(int );void delstudent();void modifyStudent();void searchStudent();
void studentProfile();void getaveragescore(int [],int ,double *);void setOrder(int );void selectSort(char [][21],int [],int ,int ,int ,char [][21]);void printUnpassed();void printAll();int menuselect();void clear();//创建e:&#92;&#92;student.txt文件,并初始化,同时计算出文件中含有的记录总数void initial(){ FILE * char choice=&#39;y&#39;; int i=0; fp=fopen(&e:&#92;&#92;student.txt&,&r&); if(!fp) {
printf(&创建文件失败,即将返回&#92;n&);
} for(;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++); count=i;}//添加学生信息void addStudent(){ FILE * char choice=&#39;y&#39;; int i=0; // fp=fopen(&e:&#92;&#92;student.txt&,&ab&); if(!fp) {
printf(&创建文件失败,即将返回&#92;n&#92;n&);
} while(choice==&#39;y&#39;) {
printf(&输入学生姓名,学号,专业,性别,中间以空格符隔开&#92;n&);
fflush(stdin);
scanf(&%s%s%s%s&,studentArray[i].name,studentArray[i].number,studentArray[i].specialty,studentArray[i].sex);
printf(&输入学生c语言分数,英语分数,数学分数&#92;n&);
scanf(&%d%d%d&,&studentArray[i].c_score,&studentArray[i].english_score,&studentArray[i].math_score);
//sum=judge(studentArray[i].c_score)+judge(studentArray[i].english_score)+judge(studentArray[i].math_score);
while(!judge(studentArray[i].c_score)||!judge(studentArray[i].english_score)||!judge(studentArray[i].math_score))
printf(&成绩输入错误,请重新输入&#92;n&);
scanf(&%d%d%d&,&studentArray[i].c_score,&studentArray[i].english_score,&studentArray[i].math_score);
//sum=judge(studentArray[i].c_score)+judge(studentArray[i].english_score)+judge(studentArray[i].math_score);
studentArray[i].total_score=studentArray[i].c_score+studentArray[i].english_score+studentArray[i].math_
fwrite(&studentArray[i],sizeof(struct student),1,fp);
//将数据写入文件中
printf(&是否继续输入,继续输入输入y或者Y,其它值退出&#92;n&);
fflush(stdin);
choice=getchar();
choice=tolower(choice);
fflush(stdin);
//清空缓存输入流 } fclose(fp); printf(&输入任意键继续&#92;n&#92;n&); getch(); //}//判断输入成绩是否合法int judge(int score){
if(score&0||score&100)
else if(score&60)
//只是为了计算后面的不及格学生相关信息
return 1;}//删除学生信息void delStudent(){FILE *fp,*fp2;int flag1=1;int flag2=0;
int found=0;
//用来标记文件中是否含有此人
char studentName[21];char studentNumber[21];fp=fopen(&e:&#92;&#92;student.txt&,&rb&);if(count==0)
printf(&文件中没有信息,即将退出&#92;n&#92;n&);
//getch();
fp2=fopen(&e:&#92;&#92;test.txt&,&wb&);
if(!fp2) {
printf(&文件创建失败,即将退出&#92;n&);
i=0; found=0; printf(&按照姓名删除请输入0,按照学号删除请输入1&#92;n&); scanf(&%d&,&flag2); fflush(stdin);
if(flag2==0)
printf(&输入要删除的学生的姓名,按回车键结束&#92;n&);
scanf(&%s&,studentName);
for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++)
//将其他人信息转移到test.txt文件中
if(strcmp(studentArray[i].name,studentName))
fwrite(&studentArray[i],sizeof(struct student),1,fp2);
fclose(fp);
fclose(fp2);
fflush(stdin);
if(found==1)
printf(&是否确认删除姓名为%s该学生信息,确认删除,输入y或者Y:&,studentName);
printf(&没有此人信息,即将退出&#92;n&);
choice=getchar();
if(choice==&#39;y&#39;||choice==&#39;Y&#39;)
//将文件结构指针重新定向
fp=fopen(&e:&#92;&#92;student.txt&,&wb&);
fp2=fopen(&e:&#92;&#92;test.txt&,&rb&);
for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp2)!=0;i++)
fwrite(&studentArray[i],sizeof(struct student),1,fp);
fclose(fp);
fclose(fp2);
} else if(flag2==1) {
printf(&输入要删除的学生的学号,按回车键结束&#92;n&);
scanf(&%s&,studentNumber);
for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++)
//将其他人信息转移到test.txt文件中
if(strcmp(studentArray[i].number,studentNumber))
fwrite(&studentArray[i],sizeof(struct student),1,fp2);
fclose(fp);
fclose(fp2);
fflush(stdin);
if(found==1)
printf(&是否确认删除学号为%s的该学生信息,确认删除,输入y或者Y:&,studentNumber);
printf(&没有此人信息,即将退出&#92;n&#92;n&);
choice=getchar();
if(choice==&#39;y&#39;||choice==&#39;Y&#39;)
//将文件结构指针重新定向
fp=fopen(&e:&#92;&#92;student.txt&,&wb&);
fp2=fopen(&e:&#92;&#92;test.txt&,&rb&);
for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp2)!=0;i++)
fwrite(&studentArray[i],sizeof(struct student),1,fp);
fclose(fp);
fclose(fp2);
printf(&输入错误&#92;n&);}//修改学生信息void modifyStudent(){ FILE *fp,*fp2; int flag=0;
char studentName[21];
fp=fopen(&e:&#92;&#92;student.txt&,&rb&); if(count==0) {
printf(&文件中还没有学生信息,即将退出&#92;n&#92;n&);
} fp2=fopen(&e:&#92;&#92;test.txt&,&wb&); if(!fp2) {
printf(&文件创建失败,即将返回&#92;n&); } printf(&输入要修改的学生的姓名&#92;n&); fflush(stdin); scanf(&%s&,studentName); for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++) {
if(!strcmp(studentArray[i].name,studentName))
printf(&输入要修改后学生的姓名,学号,专业,性别&#92;n&);
fflush(stdin);
scanf(&%s%s%s%s&,newdata.name,newdata.number,newdata.specialty,newdata.sex);
printf(&输入修改后的学生的c语言分数,英语分数,数学分数&#92;n&);
scanf(&%d%d%d&,&newdata.c_score,&newdata.english_score,&newdata.math_score);
while(!judge(studentArray[i].c_score)||!judge(studentArray[i].english_score)||!judge(studentArray[i].math_score))
printf(&输入不合法,请重新输入&#92;n&);
scanf(&%d%d%d&,&newdata.c_score,&newdata.english_score,&newdata.math_score);
newdata.total_score=newdata.c_score+newdata.english_score+newdata.math_
fwrite(&newdata,sizeof(struct student),1,fp2);
fwrite(&studentArray[i],sizeof(struct student),1,fp2); } if(flag==0) {
printf(&没有此人,即将退出&#92;n&#92;n&);
} fclose(fp); fclose(fp2); fp=fopen(&e:&#92;&#92;student.txt&,&wb&); fp2=fopen(&e:&#92;&#92;test.txt&,&rb&); for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp2)!=0;i++)
fwrite(&studentArray[i],sizeof(struct student),1,fp);
printf(&&#92;n&#92;n&); fclose(fp); fclose(fp2);}//查找某学生信息void searchStudent(){
FILE * char studentName[21]; int flag=0;
fp=fopen(&e:&#92;&#92;student.txt&,&rb&); if(count==0) {
printf(&文件中还没有学生记录,即将退出&#92;n&#92;n&);
} printf(&输入你要查找的学生姓名&#92;n&); fflush(stdin); scanf(&%s&,studentName); for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++) {
if(strcmp(studentName,studentArray[i].name)==0)
printf(&要查找的学生相关信息如下:&#92;n&);
printf(&%-10s%-15s%-20s%-5s&,putout[0],putout[1],putout[2],putout[3]);
printf(&%-6s%-6s%-6s%-6s&#92;n&, putout[4],putout[5],putout[6],putout[7]);
printf(&%-10s%-15s%-20s&,studentArray[i].name,studentArray[i].number,studentArray[i].specialty);
printf(&%-5s&,studentArray[i].sex);
printf(&%-6d%-6d&,studentArray[i].c_score,studentArray[i].english_score);
printf(&%-6d%-6d&#92;n&,studentArray[i].math_score,studentArray[i].total_score);
printf(&&#92;n&);
printf(&&#92;n&);
if(flag==0) {
printf(&没有找到姓名为%s的学生&#92;n&,studentName);
fflush(stdout);
printf(&&#92;n&);
}}//学生信息总体概况,如平均分,总人数void studentProfile(){ FILE *
int cArray[100];
//用来存储c语言分数 double cA
//用来存储c语言平均成绩 int englishArray[100];
double englishA int mathArray[100]; double mathA int totalArray[100]; double totalA fp=fopen(&e:&#92;&#92;student.txt&,&rb&); if(count==0) {
printf(&没有学生信息,即将退出&#92;n&#92;n&);
} for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++) {
cArray[i]=studentArray[i].c_
englishArray[i]=studentArray[i].english_
mathArray[i]=studentArray[i].math_
totalArray[i]=studentArray[i].total_ } printf(&共有%d个学生信息&#92;n&,count); getaveragescore(cArray,i,&cAverage); getaveragescore(englishArray,i,&englishAverage); getaveragescore(mathArray,i,&mathAverage); getaveragescore(totalArray,i,&totalAverage); printf(&c语言平均成绩为%.2f分&#92;n&,cAverage); printf(&英语平均成绩为%.2f分&#92;n&,englishAverage); printf(&数学平均成绩为%.2f分&#92;n&,mathAverage); printf(&总分平均成绩为%.2f分&#92;n&,totalAverage); printf(&&#92;n&#92;n&);}//统计平均分void getaveragescore(int arrayscore[],int n,double *averagescore){
double sum=0;
for(;i&n;i++)
sum+=arrayscore[i];
*averagescore=sum/n;}//有序输出学生的成绩void setOrder(int flag)
//flag表示选择成绩是从低到高还是从高到底排序,0从低到高,1则反之{
FILE * int i,j;
//flag=0; fp=fopen(&e:&#92;&#92;student.txt&,&rb&); if(count==0) {
printf(&没有学生信息,即将退出&#92;n&#92;n&);
} for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++);
//将数据读入结构数组中
for(choice =1;choice&5;choice++)
switch(choice)
case 1:printf(&c语言成绩:&#92;n&);
for(i=0;i&count-1;i++)
//选择排序
for(j=i+1;j&j++)
if(studentArray[i].c_score&studentArray[j].c_score)
temp=studentArray[i];
studentArray[i]=studentArray[j];
studentArray[j]=
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[4]);
for(i=0;i&i++)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].c_score);
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[4]);
for(i=count-1;i&=0;i--)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].c_score);
case 2:printf(&英语成绩:&#92;n&);
for(i=0;i&count-1;i++)
for(j=i+1;j&j++)
if(studentArray[i].english_score&studentArray[j].english_score)
temp=studentArray[i];
studentArray[i]=studentArray[j];
studentArray[j]=
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[5]);
for(i=0;i&i++)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].english_score);
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[5]);
for(i=count-1;i&=0;i--)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].english_score);
case 3:printf(&数学成绩:&#92;n&);
for(i=0;i&count-1;i++)
for(j=i+1;j&j++)
if(studentArray[i].math_score&studentArray[j].math_score)
temp=studentArray[i];
studentArray[i]=studentArray[j];
studentArray[j]=
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[6]);
for(i=0;i&i++)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].math_score);
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[6]);
for(i=count-1;i&=0;i--)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].math_score);
case 4:printf(&总成绩:&#92;n&);
for(i=0;i&count-1;i++)
for(j=i+1;j&j++)
if(studentArray[i].total_score&studentArray[j].total_score)
temp=studentArray[i];
studentArray[i]=studentArray[j];
studentArray[j]=
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[7]);
for(i=0;i&i++)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].total_score);
printf(&%-10s%-10s%-15s%-10s&#92;n&,putout[8],putout[0],putout[1],putout[7]);
for(i=count-1;i&=0;i--)
printf(&%-10d%-10s%-15s%-10d&#92;n&#92;n&,count-i,studentArray[i].name,studentArray[i].number,studentArray[i].total_score);
}}//输出不及格学生的相关信息void printUnpassed(){
int total=0; fp=fopen(&e:&#92;&#92;student.txt&,&rb&); if(count==0) {
printf(&没有学生信息,即将退出&#92;n&#92;n&);
printf(&不及格学生相关信息如下所示&#92;n&);
printf(&%-10s%-15s%-20s%-5s&,putout[0],putout[1],putout[2],putout[3]);
printf(&%-6s%-6s%-6s%-6s&#92;n&, putout[4],putout[5],putout[6],putout[7]); for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++)
if(judge(studentArray[i].c_score)+judge(studentArray[i].english_score)+judge(studentArray[i].math_score)&3)
printf(&%-10s%-15s%-20s&,studentArray[i].name,studentArray[i].number,studentArray[i].specialty);
printf(&%-5s&,studentArray[i].sex);
printf(&%-6d%-6d&,studentArray[i].c_score,studentArray[i].english_score);
printf(&%-6d%-6d&#92;n&,studentArray[i].math_score,studentArray[i].total_score);
printf(&&#92;n&);
printf(&不及格学生人数共有%d人&#92;n&#92;n&,total);
}//输出文件中所有学生信息记录void printAll(){ FILE *
// fp=fopen(&e:&#92;&#92;student.txt&,&rb&);
if(count==0) {
printf(&现在还没有学生记录,即将退出&#92;n&);
printf(&&#92;n&);
printf(&该文件中一共有%d个学生记录,记录如下:&#92;n&,count);
printf(&%-10s%-15s%-20s%-5s&,putout[0],putout[1],putout[2],putout[3]);
printf(&%-6s%-6s%-6s%-6s&#92;n&, putout[4],putout[5],putout[6],putout[7]); for(i=0;fread(&studentArray[i],sizeof(struct student),1,fp)!=0;i++) {
printf(&%-10s%-15s%-20s&,studentArray[i].name,studentArray[i].number,studentArray[i].specialty);
printf(&%-5s&,studentArray[i].sex);
printf(&%-6d%-6d&,studentArray[i].c_score,studentArray[i].english_score);
printf(&%-6d%-6d&#92;n&,studentArray[i].math_score,studentArray[i].total_score);
printf(&&#92;n&); }}void clear(){
printf(&你确认删除所有学生记录吗?继续输入y活着Y&#92;n&);
fflush(stdin);
ch=getchar();
if(ch==&#39;y&#39;||ch==&#39;Y&#39;)
fp=fopen(&e:&#92;&#92;student.txt&,&wb&);
}//主函数int main(){
printf(&**************************欢迎进入学生信息管理系统******************************&); initial(); while(1) switch(choice=menuselect()) { case 0:
printf(&************************欢迎下次再次使用*********************&#92;n&);
exit(0); case 1:
addStudent();
delStudent();
modifyStudent();
searchStudent();
studentProfile();
setOrder(0);
setOrder(1);
printUnpassed();
printAll();
system(&CLS&);
//clrscr(); case 11:
} return 0;}//菜单函数int menuselect(){
printf(&0.退出管理系统&#92;n&);
printf(&1.添加学生信息记录&#92;n&);
printf(&2.删除某一指定学生记录&#92;n&);
printf(&3.修改某一给定学生信息&#92;n&);
printf(&4.查找某一给定学生信息&#92;n&);
printf(&5.输出学生信息总体概况&#92;n&);
printf(&6.按照分数从低到高输出学生相关信息&#92;n&);
printf(&7.按照分数从高到低输出学生相关信息&#92;n&);
printf(&8.输出不及格学生的相关信息&#92;n&);
printf(&9.输出文件中所有学生的记录&#92;n&);
printf(&10.清屏&#92;n&);
printf(&11.删除所有学生记录&#92;n&);
printf(&输入你的选择:&);
scanf(&%d&,&choice);
}while(choice&0||choice&11); }
我好像有代码。。。给你找找。。。真心不好意思。。。我电脑坏了, 现在用的别人的电脑。。。忘记了。。。
⑺对于已输入的学生信息进行储存。存在哪里啊
应该是存在学生信息的系统里吧,前面不是有学生的输入吗,应该是输入完成就储存起来吧
奥,链表写?
都可以,就是C语言的程序代码就行。
# include&stdio.h&# include&malloc.h&#include&stdio.h&#include&string.h&static int &g;struct Student{ int & char name[100]; & & char faculty[100];
& &//total score,总分 //
};刚给你写的 &按照你的要求写的太长,上传原文件。。。
下一个就可以了,凌波多媒体
这个是C语言作业,要求有代码和结果
其他2条回答
为您推荐:
其他类似问题
您可能关注的内容
学生管理系统的相关知识
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 教室借用管理系统 的文章

 

随机推荐