首页 毕业设计-自动阅卷系统—论文

毕业设计-自动阅卷系统—论文

举报
开通vip

毕业设计-自动阅卷系统—论文毕业设计-自动阅卷系统—论文 自动阅卷系统 摘 要 当今社会是一个信息社会,一个知识经济时代。自世界上第一台计算机ENINC(Electronic numerical integrator and calculator)于1946年在美国问世到现在,计算机业飞速发展,技术淘汰指标高的惊人,价格下降以及软件应用的快速扩展引发了以信息处理计算机化为标志的“微机革命”,随之而来的是以全球信息 的蓬勃兴起。可见,世网络普及和全球信息共享为标志的“全球信息网络革命” 界已进入在计算机信息管理领域中激烈竞争的时代,计算机...

毕业设计-自动阅卷系统—论文
毕业 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 -自动阅卷系统— 论文 政研论文下载论文大学下载论文大学下载关于长拳的论文浙大论文封面下载 自动阅卷系统 摘 要 当今社会是一个信息社会,一个知识经济时代。自世界上第一台计算机ENINC(Electronic numerical integrator and calculator)于1946年在美国问世到现在,计算机业飞速发展,技术淘汰指标高的惊人,价格下降以及软件应用的快速扩展引发了以信息处理计算机化为标志的“微机革命”,随之而来的是以全球信息 的蓬勃兴起。可见,世网络普及和全球信息共享为标志的“全球信息网络革命” 界已进入在计算机信息管理领域中激烈竞争的时代,计算机已经变得普通的不能再普通的工具,如同我们离不开的自行车、汽车一样。我们应该承认,谁掌握的知识多,信息量大,信息处理速度快,批量大,谁的效率就高,谁就能在各种竞争中立于不败之地。 教育测量是教育过程的重要环节,它对学生的知识增长、能力发展、兴趣爱好、思想品德,以及教育措施等许多问题按一定法则进行数量化测定。它可以分为对知识的评价和对技能的评价。关于对知识测量相应的理论和技术比较成熟,通常采用客观题的形式(即选择、填空、匹配等体型)。而对于对技能的考核,既上机操作的考核,无论是理论还是实践都比较薄弱。如何解决技能考核中的环境模拟和自动阅卷是目前急需解决的两大难题。通过对国内外计算机测评系统的研究,发现早期的计算机考试主要采用卷面考试的方式,这种以理论笔试为主的考试方式,其成绩不能真正反映学生的计算机应用水平和能力,即使有在计算机上考的,大多也是 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 化的考试系统,这不仅仅是我国的计算机考试系统如此,国外也有很多考试系统也是这样。这种考试形式也会导致学生重理论、轻实践的现象的发生,考生的计算机能力大多限于“纸上谈兵”,其上机操作能力差,在新的软件工具、环境面前会束手无策 目标:通过系统对考生试卷自动进行评测,以便清晰、准确、明了的反映学生成绩的情况,实现判卷“无纸化”。 关键词: 自动阅卷系统;ACCESS; ADO Abstract Today's society is a society in an era of the knowledge economy. Since the world's first computer ENINC (Electronic numerical integerator and calculator) in the United States was made in 1946 to the present. rapid development of the computer industry, the technical indicators out of the prohibitively high. prices and the decline in software applications led to the rapid expansion of information processing computer as the symbol of the "computer revolution". attendant to the global information network is universal and global information sharing as a symbol of the "global information network revolution," the vigorous development onwards. This shows that the world has entered a fierce competition in the field of computer information management era computers have become common tools can no longer ordinary, as we can not bicycles, cars. We should recognize, the one who has mastered the knowledge, information, information processing speed, volume, whose high efficiency, Who will be able to compete in various invincible. Measurement of education is the education process and an important measure of its students to increase knowledge, skills and the development of hobbies, ideological and moral, and education measures on many issues such as a certain number of rules of conduct. It can be divided into the evaluation of the knowledge and skills evaluation. Knowledge on the measurement of the corresponding theory and technology is more mature, usually in the form of an objective that (choice to fill in the blank. matching body). As for the assessment of skills, both on the driver of the appraisal, both in theory and in practice are relatively weak. How to solve the skills assessment of the environmental simulation and automatic correction is urgently needed to resolve the two problems. Through the computer evaluation system at home and abroad study found that early examination of the computer used mainly Juanmian examinations, Such a theory-based examinations written, its results can not truly reflect the students computer application level and ability, Even if the computer examinations are mostly standardized examination system, This is not only China's computer systems of such examination, there are many foreign examination system as well. This examination will lead to the form of students theory and practice of light phenomenon, Candidates computer capacity was limited mostly to "empty talk" and its ability to operate on the difference in the new software tools, will be helpless in the face of environmental Objective : to candidates through the system automatically evaluation papers to clear, accurate, clear reflection of the performance of their students achieve Checking "paperless." Key words: Automatic scoring system;ACCESS; ADO 目 录 摘 要................................................................ 1 ABSTRACT................................................................ 2 1、 绪 论.............................................................. 6 1.1课题背景 .......................................................... 6 1.1.1目前我国自动阅卷系统的现状..................................... 7 1.1.2自动阅卷系统建设的好处......................................... 8 1.1.3开发系统的几点建议............................................. 8 1.2相关技术介绍 ...................................................... 8 1.2.1结构化生命周期法简介........................................... 8 1.2.2开发技术——快速原型法简介..................................... 9 1.2.3、ADO的背景知识............................................... 10 1.2.4本系统开发方法的选择.......................................... 10 2、系统分析............................................................ 10 2.1可行性研究 ....................................................... 11 2.1.1经济可行性.................................................... 11 2.1.2技术可行性................................................... 110 2.1.3操作可行性.................................................... 12 2.2、系统的详细调查 ................................................. 121 2..2.1系统详细设计原理............................................ 121 2.2.2自动阅卷系统的设计原理和应用................................. 121 3、系统需求分析....................................................... 132 3.1 任务概述 ........................................................ 132 3.2 系统需求 ........................................................ 132 3.2.1 Microsoft SQL Server2000数据库.............................. 143 3.2.2 MFC简述..................................................... 143 3.2.3 VC++6.0数据库访问技术...................................... 154 4、系统设计........................................................... 165 4.1 概要设计 ........................................................ 165 4.2详细设计 ........................................................ 176 4.2.1开发环境..................................................... 176 4.2.2数据库表结构设计............................................. 176 4(3数据库的详细设计 ............................................... 118 4.3.1 E-R模型..................................................... 191 4.3.2在本系统中使用ADO的过程及详解添加ADO数据源................. 192 5、程序的详细设计..................................................... 243 5.1程序设计 ........................................................ 243 5.2程序流程 ........................................................ 253 5.2.1启动界面.................................... 错误~未定义书签。24 5.2.2登陆系统.................................... 错误~未定义书签。25 5.2.3统计界面...................................................... 25 5.2.4核心代码...................................................... 26 6、 结论............................................................... 28 6.1 关键技术 ......................................................... 28 6.2 软件测试 ........................................................ 300 6.3 总结 ............................................................ 300 参考文献.............................................................. 320 谢辞.................................................................. 320 附录.................................................................. 310 1 绪 论 1.1课题背景 在现代社会中管理的作用越来越显得重要和突出。一般来讲,管理通过 计划 项目进度计划表范例计划下载计划下载计划下载课程教学计划下载 、组织、指导与领导、控制等手段,为组织制定目标,应用组织的各种要素,以实现组织的目标。对企业来说,人们按照一定的生产关系组织起来,对生产力、生产对象、生产手段等加以计划、指导、监控和协调,以达到预期的目的,即称为企业管理。传统的企业管理活动中,把人、才、物作为企业的主要资源。但是随着社会化大生产的不断扩大和社会对产品多样化的需求,人们越来越重视信息在生产经营及企业管理中的作用,并把它当作企业的一种极其重要的资源,人们称之为“信息资源”,信息资源的处理已经成为当今世界上一项主要的社会活动。 本世纪以来,由于社会生产力的迅速发展和科学技术的突飞猛进,人们进行信息交流的深度和广度不断增加,管理所需要的信息量急剧增长,同时对信息的处理要求及时、准确,这导致了传统的信息处理方法和手段已不能适应现代管理的需要;电子计算机的诞生和在信息处理中的应用,标志着一个崭新时代——“信息时代”的开始,它使企业管理现代化成为可能。 一定意义上说,管理信息系统的产生和发展是建立在电子计算机基础之上的。硬件方面,自1946年第一台电子计算机诞生以来,计算机技术的发展可谓日新月异,从庞大的只能在实验室里供研究使用的计算机到如今能适应不同环境满足不同需求的各种各样的计算机;运算速度从每秒几千次到每秒几百亿次;处理器从焊有上百万个电子管的大的惊人的电子板到只有指甲大小的集成电路;现在计算机在硬件方面的发展已达到了每三个月更新换代一次的惊人速度。软件方面,也已从机器语言、汇编语言、高级语言发展到现如今的第四代语言——非结构化、面向对象、可视化的语言。 随着计算机技术的发展和整个社会信息文化评述的不断提高,计算机已经逐 步渗透到生产、学习、生活的各个方面。将计算机技术应用于教育测量和评价的全过程中,即计算机辅助测试(Computer Assisted Test CAT)已成为国外计算机教育和教育技术领域内的一个研究热点,它从评价内容、评价方法和评价形式等多方面发展了传统测评理论和实践,并且使对信息技术能力的测评更加容易。20世纪60年代美国首先将电脑用于教育测量,如今已步入成熟应用阶段,而在国内这方面的研究才刚刚起步。 教育测量是教育过程的重要环节,它对学生的知识增长、能力发展、兴趣爱好、思想品德,以及教育措施等许多问题按一定法则进行数量化测定。它可以分为对知识的评价和对技能的评价。关于对知识测量相应的理论和技术比较成熟,通常采用客观题的形式(即选择、填空、匹配等体型)。而对于对技能的考核,既上机操作的考核,无论是理论还是实践都比较薄弱。如何解决技能考核中的环境模拟和自动阅卷是目前急需解决的两大难题。通过对国内外计算机测评系统的研究,发现早期的计算机考试主要采用卷面考试的方式,这种以理论笔试为主的考试方式,其成绩不能真正反映学生的计算机应用水平和能力,即使有在计算机上考的,大多也是标准化的考试系统,这不仅仅是我国的计算机考试系统如此, [7-9]国外也有很多考试系统也是这样。这种考试形式也会导致学生重理论、轻实践的现象的发生,考生的计算机能力大多限于“纸上谈兵”,其上机操作能力差,在新的软件工具、环境面前会束手无策。 目前,能够被实现上机考试自动阅卷的软件数目还很有限。有很多可视化界面的开发软件等待此功能的实现,以方便考生上机测试和实现现场自动批阅的目的。 近年来,随着科学技术的迅猛发展和管理水平的不断提高,计算机已经被广泛应用于日常管理之中,那么开发一套完整的自动阅卷系统已是大势所趋。 1.1.1目前我国自动阅卷系统的现状 由于种种原因,我国的信息资源建设水平远远落后于信息基础设施的建设的水平。长期以来,我国信息资源的开发管理未能与信息资源的增长同步进行。我国有丰富的原始信息资源,但在此基础上再生的二次信息系统和数据库产业的规模和市场占有率、使用率相当低,大量的有价值的信息未能进一步加工成商品使其增值。我国的计算机应用要比西方国家落后十几年,系统的开发应用是从1973 年开始的,83年以后才开始了大量的实际的开发和研究工作。因此,信息资源的开发和利用已被确立为国民经济信息的核心内容,信息数字化,传输的网络化是缩小发展中国家与发达国家差距的捷径,值世界信息化浪潮正以不可阻挡之势席卷全球时,我国要迎头赶上,就必须利用现有的信息基础设施,重点开发和推广应用于各类科技经济等数据库和网络资源服务系统,以便取得巨大的社会效益和经济效益。 由于自动阅览卷在教育中占用重要地位,其计算机化在发达国家已达到95%以上,而我国在全国范围内推广计算机在管理中的应用,是在80年代初开始的。起步虽晚,但发展快。特别是微型计算机的出现和普及,为信息处理提供了物美价廉的手段,对于推动我国管理系统处理现代化起到了重要作用。 1.1.2自动阅卷系统建设的好处 随着商业竞争的日趋激烈化,企业中管理质量的好坏,企业信息化建设的成功与否决定着企业在竞争中的成败。所以对于一个企业来说,自动阅卷系统可以提高该企业的效率,规范该企业的操作,可以提高企业的竞争力。 1.1.3开发管理信息系统的几点建议 (1)、开发系统不必贪大求全,力争简单实用。应从大处着眼,小处着手,循序渐进,逐步完善。 (2)、对开发过程中的各种文档应当注意保存。这是跨生命周期的信息管理所要求的必要条件。 (3)、尽可能取得企业领导的重视与支持,保证整个信息系统开发的顺利进行。 1.2相关技术介绍 1.2.1结构化生命周期法简介 结构化生命周期法是一种传统的管理信息系统开发方法,其基本思想是把整个系统开发过程分成若干个阶段,每个阶段进行若干活动,每项活动应用一系列标准、规范、方法和技术,完成一个或多个任务,形成符合给定规范的产品。 采用结构化生命周期法来开发管理信息系统时,应遵循的主要原则: (1)、用户参与的原则 (2)、“先逻辑后物理”的原则 (3)、“自顶向下”的原则 (4)、工作成果描述(主要指文档)标准化的原则 其具体开发步骤可分为以下四步: a系统规划 b系统开发 c系统的运行及维护 d系统评价 其中系统开发又分为以下四个步骤: (a)系统分析 .系统初步调查 .系统可行性研究 .现行系统的详细调查 .新系统逻辑 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 的提出 (b)系统设计 .系统总体结构设计 系统总体功能设计 .系统总体物理结构设计 系统详细设计 数据库设计 .代码设计 .输入输出设计 (c)系统实施 .程序设计 系统测试 1.2.2开发技术——快速原型法简介 快速原型法是80年代发展起来的,旨在缩短开发周期,提高开发效率和用户 对系统的满意程度。其基本思想是在系统开发的初期,尽快构造出系统的原型, 使用户能及早地运行这个系统原型,通过使用它、熟悉它,受到启发并取得经验, 然后对系统的目标和功能提出更精确、具体的要求,研制人员据此逐渐修改和完善原型,使它满足用户的需求,最后完成系统的开发。该方法大大提高了系统开发效率,弥补了结构化生命周期法来开发的时间长的缺陷。 通常采用原型法需要以下四个阶段: (1)、明确用户的基本要求 (2)、研制系统的原型 (3)、使用、评价系统原型 (4)、修改和完善原型 1.2.3、ADO的背景知识 Microsoft ActiveX Data Objects (ADO) 使得客户端应用程序能够通过任何 OLE.DB 提供者来访问和操作数据库服务器中的数据。 ADO 使您能够编写应用程序以通过 OLE.DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO 支持建立客户端/服务器和基于 Web 的应用程序的关键功能。 ADO 的另一个功能是“远程数据访问”(RDS),能够通过一个来回的传输将数据从服务器移动到客户端应用程序或 Web 页中,然后在客户端对数据进行操作,最后将更新数据返回服务器。RDS 先前发布的版本是 Microsoft Remote Data Service 1.5。RDS 已与 ADO 编程模块合并以简化客户端数据的远程调用。 1.2.4本系统开发方法的选择 基于以上开发方法的优劣和本系统的实际情况,本系统总体上采用结构化生命周期法进行系统规则、系统分析和系统设计,但在系统实施阶段采用原型法。 2 系统分析 系统分析,就是在管理信息系统开发的生命周期中系统分析阶段的各项活动和方法。它的主要目标是在系统规划所定的某个开发项目范围内明确系统开发的目标和用户的信息需求,提出系统的逻辑方案。系统分析在整个系统开发过程中,是要解决“做什么”的问题,把要解决哪些问题、要满足用户哪些具体的信息需求调查、分析清楚,从逻辑上或从功能需求上提出系统的方案,即“逻辑模型”。 2.1可行性研究 2.1.1经济可行性 目前基本上判卷还是完全采用纯人工方式完成,进行报表制作,对数据进行综合分析等,因此耗用工时较多,且效率低下。而当采用计算机进行管理时,不但可以为企业节省大量的人力物力,而且效率要比手工高得多,还可以让人力资源得到充分的利用。由此可见,开发此系统在经济上的是完全可行的。 2.1.2技术可行性 1、开发软件可行性 从目前市场上数据库开发、管理软件来看,对于比较简单的中小型数据库,微软公司的Microsoft SQLServer2000是实际应用中较为成功是一种解决方案。它是数据库的优秀软件,是面向对象的可视化编程,同时它提高了多库操作命令和函数,具有很强的数据处理能力。包括数据存储、分类、汇总、检索等。 同时应用Visual C++ 6.0的技术开发管理信息系统,可以得心应手,事半功倍,它为用户提供了Windows所一贯坚持的非常友好、操作简单的用户界面、完善而强大的数据操作功能,通过Visual C++ 6.0与SQL语句的结合对数据库进行更为复杂的操作。 结合本项目实际,判卷水平和复杂程度相对来说还是可以分析清楚的,经系统分析,可以设计出符合实际需求、易于理解、易于操作、易于维护的数据库和操作系统。对于Visual C++ 6.0 来说,对数量较少的表和其间关系进行比较简单的操作正是其擅长的功能,无论是查询、统计,都能顺利完成。因此,开发实施本系统,从软件的角度看,是可行的。 2、开发的硬件的可行性 开发本系统所使用的软件对于计算机硬件有一定的要求,Visual C++ 6.0 对计算机的内存、外存(主要是硬盘的容量)都有要求,这样才能是系统正常运行,基本要求是: (1)设计环境为Microsoft Windows 95或更高版本; (2)应用程序要求8MBRAM。 从目前市场上流行是硬件水平来看,这种要求水平对企业而言,是完全可以达到的。所以在硬件方面,本系统也是可行的。 2.1.3操作可行性 Windows 友好的用户界面和本系统良好的安全设置,可以使其内部员工在系统实施人员的指导帮助下很快掌握系统的使用方法。 2.2、系统的详细调查 2..2.1系统详细设计原理 系统的详细调查目标是在可行性分析的基础上进一步对原有系统进行全面、深入的调查和分析,弄清原有管理信息系统的运行状况,发现其薄弱环节,找出要解决问题的实质,确保新系统比原系统更加有效、可靠。具体内容包括:管理业务状况的调查分析、数据流程的调查分析。 系统调查可以通过发表征求意见、座谈、访问参观、参加业务实践等方法,自上而下的逐步细化了解。 通过对人员的需求调查得知,以前的管理办法,工作繁琐,工作量大,效率低。因而,建立一套管理信息系统势在必行。根据需求不同大体上可分为如下几个方面: (1) 用户的信息要求:可以实现对本用户基本信息的维护,包括学生和老师两种角色。 (2) 试卷信息的要求:及时对试卷的信息进行维护。 (3) 成绩状态的要求: 及时记录学生考试的成绩并进行维护。 (5)对数据的安全性、完整性的要求:要保证每个记录必须完整,不能被他人非法窃去。 本系统的逻辑模型主要是以系统的数据流程图和数据字典为主要描述工具,以信息系统中应有的数据流程和数据结构来描述系统。 2.2.2自动阅卷系统的设计原理和应用 为了让系统能更好更快的进行,我们制订了如下的设计思想和应用性能: (1) 系统应符合管理的规定,满足日常管理的工作需要,并达到操作过程 中的直观, 方便,实用,安全等要求; (2) 系统采用模块化程序设计方法,既便于系统功能的各种组合和修改, 又便于为参与开发的技术维护员进行维护,补充; (3) 系统应具备数据库维护功能,及时根据用户需求进行数据的添加,删 除,修改,等操作。 (4) 系统应能基本上满足本单位的内部管理功能,并且在使用管理信息 中,实现最大化的信息收集和处理,分析功能。 (5) 系统要保证安全性,对不同用户要做到权限的不同。 3 系统需求分析 3.1 任务概述 建立一个数据库,用来存储用户基本信息,试卷的基本信息及答案和成绩信息记录的数据,将这些数据登记入数据库。本项目的任务是能对数据库中的数据进行一系列的操作管理。 3.2 系统需求 硬件环境:CPU P? 550 ,内存 64M ,硬盘 20G 软件环境使用Windows2000操作系统,用visual c++ 6.0为开发平台,数据库使用SQL Server 2000,在开发此软件时用的是VC中的MFC框架。对数据的计算处理使用的是数据库字段汇总。 3.2.1 Microsoft Office Access2000数据库 Access 是Office2000里面的一个组件。是用来制作简单的数据库。 还有的意思就是访问、还有接入的意思。 如Access list 访问列表,Access point 接入点,在办公软件Office套件中,最为广大用户熟悉的是Word和Excel,因为它们功能强大且方便易用,更因为它们不仅可用于办公,还可用于个人写作和家庭记帐理财等。同为Office套件中一部分的Access,虽然有着同样强大的功能,但使用的人却相对少些,不像Word和Excel那样广泛。事实上,真正用过Access的用户,对其强大功能和灵活应用均称赞有加。 Access 数据库管理系统是Microsoft Office 套件的重要组成部分,适用于小型商务活动,用以存贮和管理商务活动所需要的数据。Access不仅是一个数据库,而且它具有强大的数据管理功能,它可以方便地利用各种数据源,生成窗体(表单),查询,报表和应用程序等。 数据库是有结构的数据集合,它与一般的数据文件不同,(其中的数据是无结构的)是一串文字或数字流。数据库中的数据可以是文字、图象、声音等。 Microsoft Access是一种关系式数据库,关系式数据库由一系列表组成,表又由一系列行和列组成,每一行是一个记录,每一列是一个字段,每个字段有一个字段名,字段名在一个表中不能重复。图1是一个“产品”表的例子。“产品”表由10个记录组成,一个记录占一行,每一个记录由产品ID、产品名称、库存量、订货量、单价和折扣率6个字段组成。“产品ID”是字段名,其下面的1,2等是字段的值。 表与表之间可以建立关系(或称关联,连接),以便查询相关联的信息。Access数据库以文件形式保存,文件的扩展名是MDB。 3.2.2 MFC简述 MFC(Microsoft Foundation Class)指的是Microsoft基础类,是用来为Windows开发C++GUI应用程序。MFC是一种十分优秀的工具,使得面向对象的软件函数包装技术演变成为一种可以进行代码复用、简化了程序的复杂性并使程序更加有效的软件开发环境..对于使用Windows API 进行应用程序开发的人员来说, MFC使程序员大大提高了程序开发效率.你不必创建GDU对象,不必编写许多代码行对这些对象进行初始化,并且小心地跟踪其生命周期的运行情况,你只需 建立一个MFC类的实例,使用其默认值,然后让撤消程序来清除系统资源即可. 3.2.3 VC++6.0数据库访问技术 Visual C++提供了多种多样的数据库访问技术―ODBC(开放数据库连接)、DAO(数据存取对象)、OLE DB和ADO(ActiveX数据对象)等。这些技术各有自己的特点,它们提供了简单、灵活、访问速度快、可扩展性强的开发技术。而ODBC是较成熟可靠的接口. ODBC(Open Database Connectivity,开放式数据库连接)是一种用来在相关或不相关的数据库管理系统(DBMS)中存取数据的标准应用程序接口(API)。是一种使用SQL语言的程序设计接口。使用ODBC让应用程序的开发人员避免了与数据源交互的复杂性。MFC ODBC是Visual C++对ODBC API封装得到的,因此可以简化程序设计。MFC类库定义了几个数据库类,通过这些类使得用户可以不须处理ODBC API中的繁杂处理就可以进行数据库操作。主要的MFC ODBC类如下。 CDatabase类:一个CDatabase对象表示一个到数据源的连接,通过它可以操作数据源。 CRecordSet类:一个CRecordSet对象代表一个从数据源选择的一组记录的集合-记录集。记录集有两种形式:snapshot和dynaset。前者表示数据的静态视图,后者表示记录集与其他用户对数据库的更新保持同步。通过CRecordSet对象,用户可以对数据库中的记录进行各种操作。 CRecordView类:CrecordView类对象能以控制形式显示数据库记录。这个视图直接连到一个CRecordSet对象的表视图。 ADO( Activex Data Objects) 是微软公司为数据库应用程序开发的com集合,是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE. DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO 在关键的应用方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。之所以称为 ADO,是用了一个比较熟悉的暗喻,OLE 自动化接口。OLE DB是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式和存储方法。在实际应用中,这种多样性意味着可以访问驻留在 Excel 电子数据表、文本文件、电子邮件/目录服务甚至邮件服务器,诸如 Microsoft Exchange 中的数据。但是,OLE DB 应用程序编程接口的目的是为各种应用程序提供最佳的功能,它并不符合简单化的要求。 4、系统设计 4.1 概要设计 本次毕业设计的内容就是设计出自动阅卷系统,在此基础上实现系统模型各个子系统的基本功能。此系统用Microsoft Office Access 2000建立一个Access数据库,用Visual C++来实现对其中数据的一系列操作,然后对学生的答案进行解析并给出成绩,通过Visual C++编程实现其中的优化处理模块。 在使用界面上,用户通过点击按钮选择相应的要进行的操作,系统经过对用户输入的有效判断,如果输入有效,根据输入的消息进行相应的处理,最后把处理结果显示到用户界面。 下面用我们用数据流图(DFD, Data Flow Diagram),也就是从数据传递和加工的角度,以图形的方式刻画数据流从输入到输出的移动变换过程。如下图所示: 查看 数据库 操作 用户选择 有效 处理 判断 数据 查询 显示 优化 结果 由上面的数据流图可以导出系统结构图。 主模块 有效 处理 数据 有效 处理 结果 数据 结果 获得输入 计算处理 给出结果 选 择 记录 优化结果 用户选择 操作结果 查询结果 4.2详细设计 4.2.1 开发环境 本系统的开发开发环境是Windows Server 2003,Visual C++ 6.0,MS Access 2003. 4.2.2数据库表结构设计 员工用户信息 UserInfo: 字段 含义 类型 为空 ID 序号 Int 否 UserSN 用户编号 nvarchar(20) 否 UserName 姓名 Nvarchar(20) 否 Pass 密码 Nvarchar(10) 否 Style 角色 Nvarchar(10) 否 试卷信息: Exam 字段 含义 类型 为空 ID 编号 Int 否 Question 考试题目 nvarchar(512) 否 Answer 正确答案 nvarchar(512) 成绩信息:Mark 字段 含义 类型 说明 ID 序号 int 否 UserSN 编号 nvarchar(10) 否 UserName 姓名 nvarchar(20) 否 Mark 成绩 nvarchar(128) 否 4(3数据库的详细设计 启动SQL2000后,屏幕出现“Microsoft Access 2000”对话框,在对 话框中选择不同的选项按钮,可新建或打开数据库。在此选择“建立数据库”, 新建一个空的数据库,名字保存为Food。在已有的数据库中创建空表主要有 三种方法:将数据直接输入到空白的数据表中,当保存新的数据时,Access 将分析数据并且自动为每一字段指定适当的数据类型及格式。使用“设计” 视图从无到有指定表的全部细节。使用表向导来选择表的字段,这些字段可 以从各样预先定义好的表中选择。此系统的数据库使用“设计”视图从无到 有创建。 再次数据库中需要创建数据表,分别存放用户信息表、题目信息表、成 绩信息表等。以创建用户信息表为例,步骤如下: (1)右击“表”图标,选择新建表,将显示一个空数据表的设计视图。 (2)按照下图所示定义表中的每一个字段。在“字段名称”列中分别 输入;在“数据类型”列中选择各字段的数据类型,当光标移动到“数据类 型”列时,光标所在的格中将出现下拉按钮,单击按钮将弹出下拉列表,其 中列出了所有的数据类型,单击选定所需要的数据类型;“说明”列用于输 入对字段的说明,可有可无。 3)保存表。保存时输入表的名称“UserInfo”。 ( (4)当我们需要将该表设置为主键时,该字段左边的灰色字段选择器 上出现一个钥匙图案,表明主关键字已经被选取。 此时用户信息表就创建好了,同样可以创建其他类型表。 4.3.1 E-R模型 为了把用户的数据要求清晰明确地表达出来,通常要建立一个概念性的 数据模型(也称为信息模型)。概念性数据模型是一种面向问题的数据模型, 是按照用户的观点来对数据和信息建模。它描述了从用户角度看到的数据, 它反映了用户的现实环境,且与在软件系统中的实现方法无关。 在本系统数据表中用到的主键有: , 用户信息表中的用户编号:UserSN , 试题信息表中的编号:ID , 成绩信息表中的编号:UserSN 4.3.2在本系统中使用ADO的过程及详解添加ADO数据源 本系统采用ADO来访问SQL数据库,这里充分应用了C++类封装的功能,根据本系统应用的范围,将访问数据库的功能函数封装在一个类CMyDatabase。 正如前所述,ADO是访问数据库的一个方法,它提供了不同的接口。ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。 _ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一 个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。 _CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。 _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口 ,然后使用_RecordsetPtr执行存储过程和SQL语句。 根据这些,我们将数据库的各种操作封装到CMyDatabase类里。几个主要函数说明如下: CMyDatabase::CMyDatabase() {//在构造函数中初始化三个接口 m_bInit=FALSE; CString szMsg; if(CoInitialize(NULL) == S_OK) { AfxMessageBox("CoInitialize already OK!"); } if (FAILED(m_pConnection.CreateInstance("ADODB.Connection"))) { szMsg.Format("Create _ConnectionPtr Instance failed:(%d)!",GetLastError()); AfxMessageBox(szMsg); return; } if (FAILED(m_pRecordPtr.CreateInstance("ADODB.Recordset"))) { szMsg.Format("Create _RecordPtr Instance failed:(%d)!",GetLastError()); AfxMessageBox(szMsg); return ; } if (FAILED(m_pCommand.CreateInstance("ADODB.Command"))) { szMsg.Format("Create _CommandPtr Instance failed:(%d)!",GetLastError()); AfxMessageBox(szMsg); return ; } m_bInit=TRUE; } CMyDatabase::~CMyDatabase() {//析构函数中释放 m_pConnection.Release(); m_pCommand.Release(); m_pRecordPtr.Release(); } BOOL CMyDatabase::Open(CString Database) { if(!m_bInit) { TRACE("Database: database init error"); return FALSE; } CString strSRC; strSRC.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='%s'", Database); TRACE("%s\r\n%s",Database,strSRC); _bstr_t bstrSRC(strSRC); m_pConnection->CursorLocation=adUseClient; //游标类型 try { m_pConnection->Open(bstrSRC,"","",-1); } catch (_com_error &e ) { CString szMsg; szMsg.Format("%s",e.ErrorMessage()); AfxMessageBox(szMsg); return FALSE; } return TRUE; } BOOL CMyDatabase::Excute(CString Sql) {//执行 SQL语句 _bstr_t bstrSql(Sql); m_pCommand->ActiveConnection=m_pConnection; m_pCommand->CommandText=bstrSql; m_pCommand->CommandType=adCmdText; m_pCommand->Parameters->Refresh(); try { m_pRecordPtr=m_pCommand->Execute(NULL,NULL,adCmdUnknown); } catch (_com_error &e ) { CString szMsg; szMsg.Format("%s",e.ErrorMessage()); AfxMessageBox(szMsg); return FALSE; } return TRUE; } void CMyDatabase::Close() { try { if(m_pConnection) { if(m_pConnection->State == adStateOpen) m_pConnection->Close(); } } catch(_com_error &e) { CString szMsg; szMsg.Format("%s",e.ErrorMessage()); AfxMessageBox(szMsg); return; } } BOOL CMyDatabase::IsEOF() {//判断记录集是否为空 if(m_pRecordPtr->GetadoEOF()) return TRUE; else return FALSE; } CString CMyDatabase::GetValueByName(CString coName) {//根据字段来取记录值 _variant_t varValue; _variant_t varName(coName); varValue = m_pRecordPtr->GetCollect(varName); CString Value=(char *)_bstr_t(varValue); CCommon::Trim(Value); return Value; } 5、程序的详细设计 5.1程序设计 该系统采用对话框形式作为主界面。系统运行时,用户首先要连接到远程 数据库,连接成功后,状态栏会有相应的提示,之后在整个系统的运行过程中,系统与数据库始终保持这一个连接,并通过这一个连接来进行各种SQL语句操作。整个系统中,主界面CFrozenFoodManageDlg 类有一个对象m_db,这个就是与数据库保存连接的数据库对象。 5.2程序流程 连接数据库 登陆系统 主界面 不同操作 5.2.1启动界面 启动程序后的主界面: 5.2.2 登陆系统 如果与数据库连接成功后,会在系统左下角提示,然后进行用户的登陆系统, 输入用户名字和密码登陆系统。 5.2.3 统计界面 教师登陆成功后,系统最下方状态栏会提示。可以对考生的成绩进行统 计。 5.2.4核心代码: 对于答案的分析,是该系统的核心部分,该系统按照SQL语句,VF语句的规则对字符串进行解析,包括对正确答案和用户答案两部分进行解析到数组里,并对两个数组进行匹配操作,如果不符合规则,可以判定是错误的,否则认为是正确答案。目前可以实现的有: 1.可以区分大小写,区分冗余空格和回车符。 2.可以区分不正确的表名 3.sql语句条件判断时区分不正确的列名 4.sql语句条件判断时候,运算符号的另义表示法.如 a a, a <= b 等价于 b >= a 5.可以识别select,delete,create,remove,drop,open,rename,update,等语句 6.对于答错的题,可以给出相应的错误说明。 在答题目时候需要注意的事项有: 写条件判断语句时候,运算符号与左右两边的数字 要一定有个空格,否则认 为答案是错的。 核心的代码见附录。 6 结论 6.1 关键技术 本系统开发过程中用到的关键技术主要有: , Visual C++与数据库的连接 , Visual C++与ADO接口 , Visual C++ 打印技术 6.2 软件测试 程序设计完毕,经过分段测试和整体测试若无错误。进行添加时候,如 果各个编号已经存则会提出相应的提示,删除前如果没有选择记录,也会相 应有提示,这样可以保证数据库的完整性,也比较人性化。 6.3 总结 在设计过程中,出现过不同的问题,开始的时候解决起来有一些困难, 经过两个月的不断学习和实践,基本上都已经解决,而且通过解决问题的过 程,总结出一些需要注意的事项: 1) 设计数据库前一定要多加考虑,减少数据的容余,保证数据的完整。 2) 系统的设计最好采用模块化,采用软件工程提倡的高聚合,低耦合。 参考文献 [1]《实用软件工程》 清华大学出版社 [2] 李闽溟、吴继刚、周学名 编著《Visual C++6.0数据库系统开发实例导航》 人民邮电出版社 [3] 谭浩强. C程序设计[M].第二版. 北京:清华大学出版社,1999 [4] 郑人杰. 软件工程(中级)[M].北京: 清华大学出版社,1999 [5] 候俊杰:深出浅入MFC [6] C++程序设计 谢辞 此毕业设计为时两个月,由于时间和能力的限制,难免出现许多不足之处,敬请各位老师批评指正。但是这一段的实践和学习,大大提高了我解决实际问题的能力,确实使我收获很多,提高很大,想信对我以后的学习生活都会大有裨益。 在此,首先要感谢我的指导老师***老师不辞劳苦的知道,使我们得以顺利完成毕业设计;其次,系里的其他的一些老师和机房的老师在毕业设计的过程中给予我们的大力支持,我从这些老师那里获益很多,在此一并表示感谢。最后,要感谢和我同组做毕业设计的同学,这份毕业设计的成果是大家共同努力的结果。谢谢大家。 附 录 部分代码如下: // AutoCheckExamDlg.cpp : implementation file // #include "stdafx.h" #include "AutoCheckExam.h" #include "AutoCheckExamDlg.h" #include "Common.h" #include "LoginDlg.h" #include "CommonFunction.h" #include "MrakDlg.h" #include "StaticMarkDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////// //////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////// //////// // CAutoCheckExamDlg dialog CAutoCheckExamDlg::CAutoCheckExamDlg(CWnd* pParent /*=NULL*/) : CDialog(CAutoCheckExamDlg::IDD, pParent) { //{{AFX_DATA_INIT(CAutoCheckExamDlg) m_sMyAnswer = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDI_MYICON); m_sExePath = ""; m_bLogin = FALSE; m_bConnected = FALSE; m_nCurrentCount = 0; m_nMdbCount =0 ; m_nMaxCount = MAX_COUNT; m_nCurrentTh = m_nMaxCount; m_bStart = FALSE; m_bIsMark = FALSE; m_nErrorNum = 0; m_nRightNum = 0; memset(&m_ExamNode,0,sizeof(m_ExamNode)); } void CAutoCheckExamDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAutoCheckExamDlg) DDX_Control(pDX, IDC_Right_BUTTON, m_RightButton); DDX_Control(pDX, IDC_VIEWMARK_BUTTON, m_ViewMark); DDX_Text(pDX, IDC_ANSWER_EDIT, m_sMyAnswer); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAutoCheckExamDlg, CDialog) //{{AFX_MSG_MAP(CAutoCheckExamDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_COMMAND(ID_LOGIN, OnLogin) ON_COMMAND(ID_CHANGEUSER, OnChangeuser) ON_COMMAND(ID_START, OnStart) ON_BN_CLICKED(ID_UPPER, OnUpper) ON_BN_CLICKED(IDC_NEXT, OnNext) ON_BN_CLICKED(IDC_CHANGEANSWER, OnChangeanswer) ON_BN_CLICKED(IDC_Submint_BUTTON, OnSubmintBUTTON) ON_COMMAND(ID_QUIT, OnQuit) ON_BN_CLICKED(IDC_SUBMITPAPER_BUTTON, OnSubmitpaperButton) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_VIEWMARK_BUTTON, OnViewmarkButton) ON_BN_CLICKED(IDC_Right_BUTTON, OnRightBUTTON) ON_COMMAND(ID_STATIC_RESULT, OnStaticResult) //}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT indicators[] = { ID_INDICATOR_NUM, // status line indicator ID_INDICATOR_NUM, ID_INDICATOR_NUM, ID_INDICATOR_NUM, ID_INDICATOR_NUM, }; ///////////////////////////////////////////////////////////////////// //////// // CAutoCheckExamDlg message handlers BOOL CAutoCheckExamDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //load the tool bar if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1)/*,CliectRect*/) { TRACE("Failed to create toolbar:%d\n",GetLastError()); return -1; // fail to create } //load the status bar if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } //format the status bar UINT nID; //控制状态栏里面的小格格 CString szTip; //--------------第一个格格,100,大小,样式 m_wndStatusBar.SetPaneInfo(0,nID,SBPS_STRETCH,100); szTip.LoadString(IDS_USER); m_wndStatusBar.SetPaneText(0,szTip); //--------------第二个格格,100,大小,样式 m_wndStatusBar.SetPaneInfo(1,nID,SBPS_STRETCH,100); szTip.LoadString(IDS_NAME); m_wndStatusBar.SetPaneText(1,szTip); //--------------第三个格格,100,大小,样式 m_wndStatusBar.SetPaneInfo(2,nID,SBPS_STRETCH,100); szTip.LoadString(IDS_STYLE); m_wndStatusBar.SetPaneText(2,szTip); //---- --- ---三 m_wndStatusBar.SetPaneInfo(3,nID,SBPS_STRETCH,200); szTip.LoadString(IDS_STARTTIME); m_wndStatusBar.SetPaneText(3,szTip); m_wndStatusBar.SetPaneInfo(4,nID,SBPS_STRETCH,100); szTip="当前状态:初始化完成"; m_wndStatusBar.SetPaneText(4,szTip); RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); CString szExePath = GetExePath(); m_sExePath = szExePath; szExePath += g_DatabaseName; if(!m_db.Open(szExePath)) { AfxMessageBox(_T("数据库初始化失败!")); return FALSE; } m_bConnected = TRUE; //读ini文件,得到最近考试题目的ID CString szIniPath; szIniPath = m_sExePath + g_IniFile; CreateIni(szIniPath); ReadFromIni(m_sNumArray,szIniPath); SetStaticProm(IDC_HAVEDONE_STATIC,0); SetStaticProm(IDC_LEFT_EXAM_STATIC,0); SetWindowText("自动阅卷系统"); return TRUE; // return TRUE unless you set the focus to a control } void CAutoCheckExamDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CAutoCheckExamDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CAutoCheckExamDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } BOOL CAutoCheckExamDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { // TODO: Add your specialized code here and/or call the base class LPTOOLTIPTEXT pPrompt; pPrompt = (LPTOOLTIPTEXT )lParam; CString szTip; switch(pPrompt->hdr.code) { case TTN_NEEDTEXT: switch(pPrompt->hdr.idFrom) { case ID_LOGIN: szTip.LoadString(ID_LOGIN); break; case ID_STOP: szTip.LoadString(ID_STOP); break; case ID_START: szTip.LoadString(ID_START); break; case ID_QUIT: szTip.LoadString(ID_QUIT); break; case ID_LOOK: szTip.LoadString(ID_LOOK); break; case ID_CHANGEUSER: szTip.LoadString(ID_CHANGEUSER); break; default: break; } strcpy(pPrompt->szText,(LPCTSTR)szTip); break; default: break; } return CDialog::OnNotify(wParam, lParam, pResult); } //成员函数 //返回队列指针 CQueueNew * CAutoCheckExamDlg::GetQueuePointer() { return &m_Queue; } CString CAutoCheckExamDlg::GetExePath() { char temp_path[_MAX_PATH]; CString path; ::GetModuleFileName(NULL, temp_path, _MAX_PATH); path = temp_path; int index = path.ReverseFind('\\'); path = path.Left(index + 1 ); //去程序名字部分 return path; } CMyDatabase * CAutoCheckExamDlg::GetDBPointer() { return &m_db; } //创建ini文件 void CAutoCheckExamDlg::CreateIni(CString &str) { CFileFind FileFind; if(!FileFind.FindFile(str)) { CFile File(str,CFile::modeCreate|CFile::modeReadWrite); } } //将最近的考试题号写入到ini中 void CAutoCheckExamDlg::WriteToIni(CStringArray &Array,CString pathfile) { CString szIn=""; int nCount = Array.GetSize(); for(int i=0;i -1) { CString szTemp; szTemp = szOut.Left(nIndex); Array.Add(szTemp); int nTempLength = szOut.GetLength(); szOut = szOut.Right(nTempLength - nIndex -1); nIndex = szOut.Find(","); TRACE("szOut:szTemp=%s,szOut=%s,nIndex=%d",szTemp,szOut,nIndex); } if(Array.GetSize() > 100) { Array.RemoveAll(); } } //设置状态拦内容 void CAutoCheckExamDlg::SetPanelText(int nID,CString str) { m_wndStatusBar.SetPaneText(nID,str); } //设置用户信息 void CAutoCheckExamDlg::SetUserInfo(CString & UserSN,CString & UserName,CString & UserStyle) { m_sUserSN = UserSN; m_sUserName = UserName; m_sStyle = UserStyle; } void CAutoCheckExamDlg::GetUserInfo(CString &UserSN, CString &UserName,CString &sStyle) { UserSN = m_sUserSN; UserName = m_sUserName; sStyle = m_sStyle; } //是否在当前数组中 BOOL CAutoCheckExamDlg::IsInArray(int &num) { CString temp; temp.Format("%d",num); int nCount = m_sNumArray.GetSize(); for(int i=0;iCorrectPaper(); //记录成绩到数据库 CMyDatabase * pDB = p->GetDBPointer(); CString szSql; CString UserSN,UserName,sStyle; int nMark = p->m_nRightNum * 10; p- >GetUserInfo(UserSN,UserName,sStyle); szSql.Format("insert into Mark(UserSN,UserName,Mark) values('%s','%s',%d)", UserSN,UserName,nMark); if(!pDB->Excute(szSql)) { AfxMessageBox(_T("成绩提交数据库失败")); } p->m_ViewMark.EnableWindow(TRUE); p->m_RightButton.EnableWindow(TRUE); p->m_bIsMark = TRUE; return 1; } CString CAutoCheckExamDlg::FormatAnswer(CString &sAnswer) { //用空格符代替回车 sAnswer.Replace('\r',' '); sAnswer.Replace('\n',' '); //格式化答案 int i=0,j=0; char * dst = ( char* )malloc(MAX_LENGTH_ANSWER); memset(dst,0,MAX_LENGTH_ANSWER); if(sAnswer.GetLength()==0) return " "; int nLength = sAnswer.GetLength(); while(i < nLength) { if(sAnswer.GetAt(i) !=' ') { dst[j]=sAnswer.GetAt(i); i++; } else { while(sAnswer.GetAt(i) == ' ') i++; dst[j]=' '; } j++; } sAnswer.Empty(); sAnswer.Format("%s",dst); sAnswer.MakeLower(); //以小写形式出现 sAnswer.TrimLeft(); //清除空白字符 sAnswer.TrimRight(); return sAnswer; } //分析Rename语句 //形如Rename view BOOL CAutoCheckExamDlg::ParseRename(CString &szCorrectAnswer, CString &MyAnswer, CString &szError) { if(MyAnswer.Find("rename view") > -1) { return TRUE; } return FALSE; } //分析update语句 //形如 update s set ..where BOOL CAutoCheckExamDlg::ParseUpdate(CString &CorrectAnswer, CString &MyAnswer, CString &szError) { if(CorrectAnswer == MyAnswer) {//考生答案就是正确答案 return TRUE; } int nMyFromIndex = MyAnswer.Find("from"); //update语句没有from if(nMyFromIndex > -1) { szError = "update 语法不正确"; return FALSE; } int nMySetIndex = MyAnswer.Find("set"); //update语句没有from if(nMySetIndex == -1) { szError = "update 语法不正确"; return FALSE; } //判断运算符号 int nCorrectWhereIndex = CorrectAnswer.Find("where"); int nMyWhereIndex = MyAnswer.Find("where"); if(!((nMyWhereIndex == -1) && (nCorrectWhereIndex == -1))) { szError = "查询条件不匹配"; return FALSE; } else if(((nMyWhereIndex == -1) && (nCorrectWhereIndex == -1))) { return TRUE; } //首先判断 where a.字段 <= b.字段 (运算符号左右至少有一个空格) //a<=b 等价于 b>=a //aa //a==b 等价于 b==a CStringArray CorrectFilterArray,MyFilterArray; GetFilter(CorrectAnswer,nCorrectWhereIndex+6,CorrectFilterArray); GetFilter(MyAnswer,nMyWhereIndex+6,MyFilterArray); if(!CompareFilter(CorrectFilterArray,MyFilterArray)) { szError = "运算条件错误"; return FALSE; } return TRUE; } //分析open语句 //形如 open database s BOOL CAutoCheckExamDlg::ParseOpen(CString &szCorrectAnswer, CString &szMyAnswer, CString &szError) { if(szMyAnswer.Find("open database") > -1) { return TRUE; } return FALSE; } //分析Remove语句 //行如 Remove table s,drop view s BOOL CAutoCheckExamDlg::ParseRemove(CString &szCorrectAnswer, CString &szMyAnswer, CString szError) { if(szMyAnswer.Find("remove table")) { return TRUE; } return FALSE; } //分析Drop语句 //行如 Drop table s,drop view s BOOL CAutoCheckExamDlg::ParseDrop(CString &szCorrectAnswer, CString &szMyAnswer, CString &szError) { if((szCorrectAnswer.Find("drop table") > -1) && (szMyAnswer.Find("drop table") > -1) ) {//删除数据库表 drop table student return TRUE; } else if( ((szCorrectAnswer.Find("drop table") == -1) && (szCorrectAnswer.Find("drop view") > -1)) &&((szMyAnswer.Find("drop") == -1) && (szMyAnswer.Find("drop view") > -1)) ) {//删除视图 drop view student return TRUE; } return FALSE; } //分析Create语句 //行如 create database s,create s BOOL CAutoCheckExamDlg::ParseCreate(CString &szCorrectAnswer, CString &szMyAnswer, CString &szError) { if((szCorrectAnswer.Find("create database") > -1) && (szMyAnswer.Find("create database") > -1) ) {//创建数据库文件 create database student return TRUE; } else if( ((szCorrectAnswer.Find("create database") == -1) && (szCorrectAnswer.Find("create") > -1)) &&((szMyAnswer.Find("create database") == -1) && (szMyAnswer.Find("create") > -1)) ) {//创建数据表 create student return TRUE; } return FALSE; } //分析select 语句 //形如 select * from 表名1,表名2 where 条件 //分析重点:(1)from关键字,(2)where 关键字 (3)表名是否匹配 (4) 判断条件 中 <,> ,=等运算符号 BOOL CAutoCheckExamDlg::ParseSelect(CString &CorrectAnswer, CString &MyAnswer, CString &szError) { if(CorrectAnswer == MyAnswer) {//考生答案就是正确答案 return TRUE; } int nMyFromIndex = MyAnswer.Find("from"); if(nMyFromIndex == -1) { szError = "select 语法不正确"; return FALSE; } //有from情况下比较 表名 CStringArray MyTableArray,CorrectTableArray; GetTableName(MyAnswer,nMyFromIndex+5,MyTableArray); int nCorrectFromIndex = CorrectAnswer.Find("from"); GetTableName(CorrectAnswer,nCorrectFromIndex+5,CorrectTableArray) ; //比较表名是否一样 if(!CompareTableName(CorrectTableArray,MyTableArray)) { szError = "from 语法不正确:表名不相符"; return FALSE; } //判断运算符号 int nCorrectWhereIndex = CorrectAnswer.Find("where"); int nMyWhereIndex = MyAnswer.Find("where"); if( ((nMyWhereIndex == -1) && (nCorrectWhereIndex > -1)) ||((nMyWhereIndex > -1) && (nCorrectWhereIndex == -1)) ) { szError = "查询条件不匹配"; return FALSE; } else if(((nMyWhereIndex == -1) && (nCorrectWhereIndex == -1))) { return TRUE; } //首先判断 where a.字段 <= b.字段 (运算符号左右至少有一个空格) //a<=b 等价于 b>=a //aa //a==b 等价于 b==a CStringArray CorrectFilterArray,MyFilterArray; GetFilter(CorrectAnswer,nCorrectWhereIndex+6,CorrectFilterArray); GetFilter(MyAnswer,nMyWhereIndex+6,MyFilterArray); if(!CompareFilter(CorrectFilterArray,MyFilterArray)) { szError = "运算条件错误"; return FALSE; } return TRUE; } //分析delete语句 //形如 delete from 表名1,表名2 where 条件 //分析重点:(1)from关键字,(2)where 关键字 (3)表名是否匹配 (4) 判断条件 中 <,> ,=等运算符号 BOOL CAutoCheckExamDlg::ParseDelete(CString & CorrectAnswer,CString & MyAnswer,CString & szError) { if(CorrectAnswer == MyAnswer) {//考生答案就是正确答案 return TRUE; } int nMyFromIndex = MyAnswer.Find("from"); if(nMyFromIndex == -1) { szError = "delete 语法不正确"; return FALSE; } //有from情况下比较 表名 CStringArray MyTableArray,CorrectTableArray; GetTableName(MyAnswer,nMyFromIndex+5,MyTableArray); int nCorrectFromIndex = CorrectAnswer.Find("from"); GetTableName(CorrectAnswer,nCorrectFromIndex+5,CorrectTableArray) ; //比较表名是否一样 if(!CompareTableName(CorrectTableArray,MyTableArray)) { szError = "delete 语法不正确:表名不够"; return FALSE; } //判断运算符号 int nCorrectWhereIndex = CorrectAnswer.Find("where"); int nMyWhereIndex = MyAnswer.Find("where"); if(!((nMyWhereIndex == -1) && (nCorrectWhereIndex == -1))) { szError = "查询条件不匹配"; return FALSE; } else if(((nMyWhereIndex == -1) && (nCorrectWhereIndex == -1))) { return TRUE; } //首先判断 where a.字段 <= b.字段 (运算符号左右至少有一个空格) //a<=b 等价于 b>=a //aa //a==b 等价于 b==a CStringArray CorrectFilterArray,MyFilterArray; GetFilter(CorrectAnswer,nCorrectWhereIndex+6,CorrectFilterArray); GetFilter(MyAnswer,nMyWhereIndex+6,MyFilterArray); if(!CompareFilter(CorrectFilterArray,MyFilterArray)) { szError = "运算条件错误"; return FALSE; } return TRUE; } //比较两个数组里表名是否一样 BOOL CAutoCheckExamDlg::CompareTableName(CStringArray &CorrectArray, CStringArray &MyArray) { int nCorrectSize =CorrectArray.GetSize(); int nMySize = MyArray.GetSize(); if( nCorrectSize != nMySize) { return FALSE; } for(int i=0;i') { return TRUE; } return FALSE; } //从答案中提取where后面的条件 void CAutoCheckExamDlg::GetFilter(const CString &sAnswer, const int nIndex, CStringArray &ResultArray) { int nLength = sAnswer.GetLength(); int i = nIndex; int nStart = i; CString szTemp; while (i=")) //<=和>=相反 ||((CorrectArray.GetAt(1) == "<") && (MyArray.GetAt(1) == ">")) //<和>相反 ||((CorrectArray.GetAt(1) == ">=") && (MyArray.GetAt(1) == "<=")) //>=和<=相反 ||((CorrectArray.GetAt(1) == ">") && (MyArray.GetAt(1) == "<")) //<和>相反 ) //符号相反,看左右是否一样 { if((CorrectArray.GetAt(0) == MyArray.GetAt(2)) &&(CorrectArray.GetAt(2) == MyArray.GetAt(0)) )//运算值相反 { return TRUE; } else { return FALSE; } } else { return FALSE; } } return FALSE; } //从答案中提取表名 ad,bdd,d void CAutoCheckExamDlg::GetTableName(CString &sAnswer, int nIndex, CStringArray & ResultArray) { int nLength = sAnswer.GetLength(); int i = nIndex; int nStart = i; CString szTemp; while((iAnswer); //保存正确答案 szMyAnswer.Format("%s",p->MyAnswer); //保存考生答案 //格式化答案 FormatAnswer(szCorrectAnswer); FormatAnswer(szMyAnswer); if(szCorrectAnswer == szMyAnswer) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; continue; } //得到答案第一个词:selete,delete,create,list... szCorrectFirst = FindFirstWord(szCorrectAnswer); szMyFirst = FindFirstWord(szMyAnswer); //判断第一个词是否一样 if(szMyFirst != szCorrectFirst) {//第一个词命令不正确,可以确保答案是错误的 szError = _T("选用的函数错误"); ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { if(szMyFirst == "select") { if(!ParseSelect(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "delete") { if(!ParseDelete(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "create") { if(!ParseCreate(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "drop") { if(!ParseDrop(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "open") { if(!ParseOpen(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "remove") { if(!ParseRemove(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "update") { if(!ParseUpdate(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; >Other,szError); strcpy(ObjExamNode- m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else if(szMyFirst == "rename") { if(!ParseUpdate(szCorrectAnswer,szMyAnswer,szError)) { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = CORRECT; ObjExamNode->nStyle = CHECK; m_nRightNum++; } } else { ExamNode * ObjExamNode = m_Queue.GetExamNode(p->nIndex); ObjExamNode->Mark = WRONG; ObjExamNode->nStyle = CHECK; strcpy(ObjExamNode->Other,szError); m_nErrorNum++; } } } } } CString CAutoCheckExamDlg::FindFirstWord(CString szAnswer) { int nIndex = szAnswer.Find(" "); CString szFirst; szFirst = szAnswer.Left(nIndex); return szFirst; } //*********88 以下为控件响应函数 void CAutoCheckExamDlg::OnCancel() { // TODO: Add extra cleanup here m_db.Close(); CDialog::OnCancel(); } //登陆 void CAutoCheckExamDlg::OnLogin() { // TODO: Add your command handler code here Init(); CLoginDlg LoginDlg; if(LoginDlg.DoModal() == IDOK) { CString szTip; szTip.Format("用户:%s",m_sUserSN); SetPanelText(0,szTip); szTip.Format("姓名:%s",m_sUserName); SetPanelText(1,szTip); szTip.Format("角色:%s",m_sStyle); SetPanelText(2,szTip); m_bLogin = TRUE; } else { AfxMessageBox("没有登陆"); m_bLogin = FALSE; } m_nCurrentCount = 0; } //切换用户 void CAutoCheckExamDlg::OnChangeuser() { // TODO: Add your command handler code here Init(); CLoginDlg LoginDlg; if(LoginDlg.DoModal() == IDOK) { CString szTip; szTip.Format("用户:%s",m_sUserSN); SetPanelText(0,szTip); szTip.Format("姓名:%s",m_sUserName); SetPanelText(1,szTip); szTip.Format("角色:%s",m_sStyle); SetPanelText(2,szTip); m_bLogin = TRUE; } else { AfxMessageBox("没有登陆"); m_bLogin = FALSE; } m_nCurrentCount = 0; } //开始 void CAutoCheckExamDlg::OnStart() { // TODO: Add your command handler code here if(!m_bLogin) { AfxMessageBox(_T("请先登陆系统")); return ; } //设置状态栏 CString szTime; CTime t = CTime::GetCurrentTime(); szTime.Format("开始时 间:%d-%d-%d %d:%d:%d",t.GetYear(),t.GetMonth(),t.GetDay(),t.GetHour() ,t.GetMinute(),t.GetSecond()); SetPanelText(3,szTime); SetPanelText(4,"当前状态:正在考试..."); CString szSql; szSql.Format("select * from exam"); if(!m_db.Excute(szSql)) { AfxMessageBox("查询数据库出错1"); return ; } while(!m_db.IsEOF()) { m_nMdbCount++; m_db.MoveNext(); } if(m_nMdbCount <= MAX_COUNT) { if(MessageBox("题库量较小,确定要继续吗?","警告",MB_OKCANCEL) == IDOK) {//继续 m_nMaxCount = m_nMdbCount; //数据库中题量小,将数据库总数赋最大值 m_nCurrentTh = m_nMaxCount; } else { return ; } } SetStaticProm(IDC_HAVEDONE_STATIC,m_nCurrentCount); SetStaticProm(IDC_LEFT_EXAM_STATIC,m_nMaxCount-m_nCurrentCount); if(m_nCurrentCount Question); m_sMyAnswer = pNode->MyAnswer; SetExamNum(m_nCurrentTh); UpdateData(FALSE); } //下一道 void CAutoCheckExamDlg::OnNext() { // TODO: Add your control notification handler code here if(m_nCurrentCount != m_nMaxCount) { AfxMessageBox(_T("答完所有的题目后才可以进行查看")); return ; } if(m_nCurrentTh == m_nMaxCount) { AfxMessageBox(_T("已经是最后一道")); return ; } m_nCurrentTh++; ExamNode * pNode = NULL; pNode = m_Queue.GetExamNode(m_nCurrentTh); ASSERT(pNode!=NULL); //显示结果 SetDlgItemText(IDC_EXAM_STATIC,pNode->Question); m_sMyAnswer = pNode->MyAnswer; SetExamNum(m_nCurrentTh); UpdateData(FALSE); } //修改答案 void CAutoCheckExamDlg::OnChangeanswer() { // TODO: Add your control notification handler code here if(m_nCurrentCount != m_nMaxCount) { AfxMessageBox(_T("答完所有的题目后才可以进行修改")); return ; } UpdateData(TRUE); CCommonFunction::Trim(m_sMyAnswer); ExamNode * pNode = NULL; pNode = m_Queue.GetExamNode(m_nCurrentTh); ASSERT(pNode!=NULL); memset(pNode->MyAnswer,0,sizeof(pNode->MyAnswer)); memcpy(pNode->MyAnswer,m_sMyAnswer,sizeof(pNode->MyAnswer)); AfxMessageBox(_T("修改成功")); } //提交 void CAutoCheckExamDlg::OnSubmintBUTTON() { // TODO: Add your control notification handler code here TRACE("submit m_nCurrentCount=%d,m_nMaxCount=%d",m_nCurrentCount,m_nMaxCount); UpdateData(TRUE); if(!m_bStart) { AfxMessageBox(_T("考试已经停止")); return ; } CCommonFunction::Trim(m_sMyAnswer); if(m_sMyAnswer.GetLength() == 0) { AfxMessageBox(_T("请输入答案")); return ; } //将该题自己的答案信息保存到队列 memcpy(m_ExamNode.MyAnswer,m_sMyAnswer,sizeof(m_ExamNode.MyAnswer )); m_ExamNode.nStyle = SUBMIT; //生成新结点保存到队列 ExamNode * pExamNode = new ExamNode; memset(pExamNode,0,sizeof(ExamNode)); memcpy(pExamNode,&m_ExamNode,sizeof(ExamNode)); m_Queue.Add(pExamNode); //设置题目提示信息 SetStaticProm(IDC_HAVEDONE_STATIC,m_nCurrentCount); SetStaticProm(IDC_LEFT_EXAM_STATIC,m_nMaxCount-m_nCurrentCount); m_sMyAnswer = ""; //取得下一题进行分析 if(m_nCurrentCount < m_nMaxCount) { GetOneQuestion(); //随机选择一道题目 m_nCurrentCount++; SetExamNum(m_nCurrentCount); } else if(m_nCurrentCount == m_nMaxCount) {//答题结束 CString szMsg; szMsg.Format(_T("答题结束.请确认无需修改之后点 提交试卷")); AfxMessageBox(szMsg); GetDlgItem(IDC_SUBMITPAPER_BUTTON)->EnableWindow(TRUE); m_bStart = FALSE; WriteToIni(m_sNumArray,m_sExePath+g_IniFile); //记录最近的考试题号 return ; } UpdateData(FALSE); } void CAutoCheckExamDlg::OnButton1() {//打印Queue // TODO: Add your control notification handler code here CCommonFunction::WriteToLog(m_Queue); } void CAutoCheckExamDlg::OnQuit() { // TODO: Add your command handler code here m_db.Close(); m_Queue.Destroy(); CDialog::OnCancel(); } void CAutoCheckExamDlg::OnSubmitpaperButton() { // TODO: Add your control notification handler code here CreateThread(NULL,0,ProcessMark,this,0,NULL); CString szMsg; szMsg.Format(_T("系统正在处理,请梢后查看成绩...")); AfxMessageBox(szMsg); } void CAutoCheckExamDlg::OnViewmarkButton() { // TODO: Add your control notification handler code here if(!m_bIsMark) { AfxMessageBox(_T("请考试完后查看结果!")); return ; } CMrakDlg MarkDlg; MarkDlg.SetParent(this); MarkDlg.DoModal(); } void CAutoCheckExamDlg::OnRightBUTTON() { // TODO: Add your control notification handler code here CString szPathFile; szPathFile = m_sExePath + g_LogFile; CFileFind filefind; if(filefind.FindFile(szPathFile)) { DeleteFile(szPathFile); } if(CCommonFunction::WriteRightAnswerLog(m_Queue,(LPCTSTR)szPathFi le)) { CString szMsg; szMsg.Format(_T("已将结果输出到当前目录下的 %s文件中,请查看"),g_LogFile); AfxMessageBox(szMsg); } } //统计结果 void CAutoCheckExamDlg::OnStaticResult() { // TODO: Add your command handler code here if(m_sStyle != "老师") { AfxMessageBox(_T("只有教师用户才有此权限")); return ; } CStaticMarkDlg dlg; dlg.SetParent(this); dlg.DoModal(); } // CommonFunction.cpp: implementation of the CCommonFunction class. // ///////////////////////////////////////////////////////////////////// / #include "stdafx.h" #include "AutoCheckExam.h" #include "CommonFunction.h" #include "Common.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ///////////////////////////////////////////////////////////////////// / // Construction/Destruction ///////////////////////////////////////////////////////////////////// / CCommonFunction::CCommonFunction() { } CCommonFunction::~CCommonFunction() { } CCommonFunction::Trim(CString &str) { str.TrimLeft(); str.TrimRight(); } int CCommonFunction::WriteToLog(CQueueNew & Queue) //overload function,Log function { FILE* log; log = fopen(LOGFILE, "a+"); if (log == NULL){ OutputDebugString("Log file open failed."); return -1; } ExamNode* ptemp = Queue.GetHeader(); ptemp = ptemp->next; for(int i=0;inext) { fprintf(log,"*** *** **** *** *** new packet *** *** *** ***\n"); fprintf(log,"%d\n",ptemp->nIndex); fprintf(log,"%d\n",ptemp->nID); fprintf(log,"%d\n",ptemp->nStyle); fprintf(log,"%s\n",ptemp->Question); fprintf(log,"%s\n",ptemp->Answer); fprintf(log,"%s\n",ptemp->MyAnswer); fprintf(log,"%d\n",ptemp->Mark); fprintf(log,"**** *** *** *** *** new packet over *** *** *** ***\n\n"); } fclose(log); return 0; } BOOL CCommonFunction::WriteRightAnswerLog(CQueueNew & Queue,const char * file) //overload function,Log function { FILE* log; CString szMsg; log = fopen(file, "a+"); if (log == NULL){ OutputDebugString("Log file open failed."); return FALSE; } ExamNode* ptemp = Queue.GetHeader(); ptemp = ptemp->next; for(int i=0;inext) { fprintf(log,"*** *** **** *** *** new *** *** *** ***\n"); szMsg.Format("题号:%d",ptemp->nIndex); fprintf(log,"%s\n",szMsg); szMsg.Format("问题:%s",ptemp->Question); fprintf(log,"%s\n",szMsg); szMsg.Format("正确答案:%s",ptemp->Answer); fprintf(log,"%s\n",szMsg); szMsg.Format("我的答案:%s",ptemp->MyAnswer); fprintf(log,"%s\n",szMsg); szMsg.Format("得分:%d",ptemp->Mark); fprintf(log,"%s\n",szMsg); fprintf(log,"**** *** *** *** *** new over *** *** *** ***\n\n"); } fclose(log); return TRUE; } void CCommonFunction::ShowMessageBox(int i) { CString str; str.Format("%d",i); AfxMessageBox(str); } void CCommonFunction::Encrypt(CString & str) { //加密 char strpass[MAX_PASS_LENGTH+1]; //申请内存 int nLength = str.GetLength(); memset(strpass,0,sizeof(strpass)); strcpy(strpass,str); //将CString的值赋给数祖 for(int i=0;i
本文档为【毕业设计-自动阅卷系统—论文】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_650122
暂无简介~
格式:doc
大小:260KB
软件:Word
页数:0
分类:工学
上传时间:2017-11-11
浏览量:54