项目设计:
单位:
怀化学院计算机科学与工程学院
计算机科学与技术专业
课程 | c语言高级程序项目设计 |
---|---|
班级,组号 | 1901班,第二组 |
团队名称 | 我行,我C! |
组员 | 袁年财(组长),王乐,杨令 |
课题 | 多功能测验程序 |
功能模块一:登录
1)连接服务器,限制账号要以10位学号+姓名的方式登录,否则就重新登录
2)登录成功后将基本信息发送给服务器
3)登录成功后将窗口标题修改为账号名
功能模块二:预备工作
1)修改窗口名之后,输出测验相关的提示信息、限时信息等
2)生成以用户名命名的TXT文件
3)输出测验的相关提示信息(如限时与限 题)
4)答题前倒计时5秒(若为单机版联系版,可由用户自行设定)
功能模块三:答题与记录
1)从题库中抽取随机不重复的题(按一定的难易比例抽取)
2)输出相应的题号与题目
3)提示用户输入答案
4)处理用户的答案去掉开头的误输空格与回车,还有中间的空格
5)判断用户答案正误,输出比较结果,正确则用绿色表示,错误则用红色表示(便于用户识别)
6)同时输出所耗时间,所耗总时间,以答题数,正确题数
7)并将以上答题的过程信息记录至TXT文档之中
8)超时或者答完所有题之后,输出总成绩与评价,但不关闭程序,由用户自行输入一定指令后退出程序
功能模块四:上传成绩
1)若考生成绩达到某个级别,将生成【学生基本_EXAM.TXT】在服务器之下,记录保存。
——————————————————————————————————————
——————————————————————————————————————
已实现功能:
1、连接服务器
①实现思想:利用Socket
②核心代码:如下
#include
#include
#include
#pragma comment(lib , "ws2_32.lib")
#define BUFSIZE 4096 /*缓冲区大小*/
#define PORT 0
#define IP 1
int main( )
{
WSADATA wsd;
SOCKET sClient;
char Buffer[BUFSIZE];
int ret;
struct sockaddr_in server;
unsigned short port;
struct hostent *host = NULL;
char getparameter[2][30];
printf("请输入服务器端口号:");
gets(getparameter[PORT]);
printf("请输入服务器IP地址:");
gets(getparameter[IP]);
/*加载Winsock DLL*/
if (WSAStartup(MAKEWORD(2 , 2) , &wsd) != 0) {
printf("Winsock 初始化失败!\n");
return 1;
}
/*创建Socket*/
sClient = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if (sClient == INVALID_SOCKET) {
printf("socket() 失败: %d\n" , WSAGetLastError());
return 1;
}
/*指定服务器地址*/
server.sin_family = AF_INET;
port = atoi(getparameter[PORT]);
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(getparameter[IP]);
if (server.sin_addr.s_addr == INADDR_NONE) {
host = gethostbyname(getparameter[IP]); //输入的地址可能是域名等
if (host == NULL) {
printf("无法解析服务端地址: %s\n" , getparameter[IP]);
return 1;
}
CopyMemory(&server.sin_addr ,
host->h_addr_list[0] ,
host->h_length);
}
/*与服务器建立连接*/
if (connect(sClient , (struct sockaddr*)&server ,
sizeof(server)) == SOCKET_ERROR) {
printf("connect() 失败: %d\n" , WSAGetLastError());
return 1;
}
//用完了,关闭socket句柄(文件描述符)
closesocket(sClient);
WSACleanup(); //清理
return 0;
}
③效果图:
2、发送信息至服务器
①实现思想:从标准输入读取要发送的数据
②核心代码:如下
//向服务器发送消息
ret = send(sClient , array , strlen(array) , 0);//其中array为你想要发送到服务器的信息所存放的数组
if (ret == 0)
{
break;
}
else if (ret == SOCKET_ERROR)
{
printf("send() 失败: %d\n" , WSAGetLastError());
break;
}`
3、限制账号要以10位学号+姓名的方式登录,否则重新登录
①实现思想:判断前十位是否为数字即可
②核心代码:如下
void restrictedformat(char *array)//限制学号格式
{
int g,count3=0;
for(g=0;g<10;g++)
{
if(array[g]>='0' && array[g]<='9')
{
count3=count3+1;
}
else
{
print("格式错误\n");
}
if(count3==10)
{
print("格式正确n");
}
}
}
4、将窗口标题修改为账号名
①实现思想:调用库函数SetConsoleTitle
②核心代码:如下
void modifytitle(char *account)//改窗口
{
SetConsoleTitle(account);
}`
5、生成TXT文件,并向其中输入答题过程信息
①实现思想:实现对文件的创建、打开和关闭并向其中输入信息
②核心代码:如下
FILE * file
if( (file = fopen(mymessage,"w")) == NULL )
{
printf("打开文件失败\n");
exit(0);
}`
fprintf(file,"%s本次的成绩单:\n↓ ↓ ↓\n",mymessage); //此语句用来向文件中输入内容
6、每次答完题后都将内容输入至文件中
①实现思想:在每答完一道题之后清空缓冲区,以保证答题过程信息及时的记录其中
②核心代码:如下
fflush(file);//随着循环自动刷新文件内存缓冲区,可在答完每一道题之后向文件输入答题过程信息
//参考链接:https://blog.csdn.net/zgdzjzz/article/details/98882466
7、可限制时间答题
①实现思想:利用时间函数
②核心代码:如下
//使用时需要有 #include
clock_t start_t,finish_t;//定义有关时间的变量
start_t = clock();//过程时间开始计时点
.
.//此处为需要计时的程序
.
finish_t = clock();//过程时间结束计时点
total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC;//算出时间,并将时间转换为秒
③效果图:
8、从题库中随机抽题
①实现思想:产生随机数
②核心代码:如下
/*使用时需要有以下两个头文件
#include
#include */
int a;
srand((unsigned)time(NULL));
a = rand();
printf("%d\n", a);
③效果图:
以下只是产生随机数的例子并不是上面的程序执行的结果,用于抽题时,则表现为每出一道的题都为随机抽取
9、去除用户开头误输的空格、回车和答案中的空格
①实现思想:运用getschar
②核心代码:如下
void myrellyanswer(char *array)//输入答案的处理用户答案的函数
{
char d;
int i=0;
do
{
d=getchar();
}
while(d=='\n'||d==' ');
array[i]=d;
i++;
while(1)
{
d=getchar();
if(d==' ')
{
continue;
}
else if(d=='\n')
{
break;
}
else
{
array[i]=d;
i++;
}
}
array[i]='\0';
}
③效果图:
10、用不同的颜色输出相关信息
①实现思想:调用库函数
②核心代码:如下
void color(int x) //自定义函根据参数改变颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);//只有一个参数,输入颜色代号即可改变为相应的颜色
}
11、设置相应的评分标准
①实现思想:利用分支语句
②核心代码:如下
switch(x)
{
case 2 :show_mymessage(14,file," 你的成绩为C\n 还不错> v <!!!\n\n");
break;
case 3 :show_mymessage(11,file," 你的成绩为B\n 真优秀^ _ ^!!!\n\n");
break;
case 5 :show_mymessage(3,file," 你的成绩为A\n 造化钟神秀^ v ^!!!\n\n");
break;
default :show_mymessage(13,file," 不合格> _ <!!!\n\n");
}
12、将改颜色的函数、输出的函数和输入信息至文档的函数封装为一个函数
①实现思想:参照链接:此处为示例封装函数的地址
②核心代码:如下
void show_mymessage(int x,FILE *file,const char *cmd, ...)//输出有色内容的同时输入至文件中
{
va_list args;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
va_start(args,cmd);
vprintf(cmd,args);
vfprintf(file,cmd,args);
va_end(args);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
③效果图:
—————————————————————————————————————
1.按百分比输出难题和简单的题
还未实现,仍然需要时间去摸索更为的简便方法
1.若考生成绩达到某个级别,将发送到服务器的答题过程信息保存在服务器下
还需要系统的学习关于网络编程的相关知识,并灵活运用
——————————————————————————————————————
版本号 | 更新描述 | 负责人 | 日期 | 占总工作量的百分比 |
---|---|---|---|---|
V2.0.1 | 实现了联机版:可以自定义连接服务器,并向服务器发送一定的信息 | 袁年财 | 11/24/ 02:10 | 5% |
V1.5.5 | 答完题后显示评分细则 | 王乐 | 11/23/ 22:30 | 3.4% |
V1.5.4 | 在用户答完题后,按任意键不会退出,在输入一定内容后才可退出 | 王乐,袁年财 | 11/23/ 23:30 | 4.2% |
V1.5.3 | 精确判断学号格式只能是 1(8或9)00130XXX 的形式使程序仅限于计院的18和19级学生使用 | 袁年财 | 11/23/ 19:30 | 4.2% |
V1.5.2 | 优化了文件输入功能,可在答完每一道题后,将答题过程信息输入至文件夹文件夹,以防在失误关闭程序后答题过程信息丢失 | 袁年财 | 11/23/ 18:30 | 4.2% |
V1.5.1 | 优化了界面,在完成准备流程后的答题前清空屏幕 | 杨令 | 11/22/ 12:20 | 4.2% |
V1.5.0 | 优化了题库,利用分割数组的方法将答案与原题绑在一起,便于添加题目,同时又可防止比较答案时题目与答案错位 | 袁年财 | 11/22/ 1:10 | 4.2% |
V1.4.6 | 在题库中新增了大量难题和易题 | 杨令 | 11/21/18:10 | 4.2% |
V1.4.5 | 完善了防误输功能,可以防止因用户在答题时在开头误输回车而导致答题错误 | 袁年财 | 11/21/18:10 | 4.2% |
V1.4.4 | 在用户输入学号+姓名之后,判定学号格式是否为10位数字的格式 | 袁年财 | 11/21/ 9:30 | 4.2% |
V1.4.3 | 新增了评级判定功能 | 王乐 | 11/20/20:50 | 4.2% |
V1.4.2 | 增加了防误输功能,防止因用户在答案中误输空格而导致答题错误 | 袁年财 | 11/19/18:10 | 2.6% |
V1.4.1 | 新增了记录用户答题过程信息,并记录在相应路径的以用户名为名的TXT文件中 | 王乐 | 11/18/21:12 | 4.2% |
V1.3.2 | 新增了输入用户信息之后,将窗口改为用户名 | 袁年财 | 11/18/21:12 | 4.2% |
V1.3.1 | 完善了计时功能,每答出一道题后输出所用总时间的同时,输出回答该题所用时间 | 袁年财 | 11/17/20:40 | 4.2% |
V1.3.0 | 新增更改字体颜色函数,使程序在视觉上不会过于单调 | 袁年财 | 11/17/18:30 | 4.2% |
V1.2.1 | 新增了开始答题前倒计时5秒功能 | 袁年财 | 11/17/16:10 | 4.2% |
V1.2.0 | 新增计时功能:每答出一道题输出总时间。新增了每次回答题目后都输出已答对提数 | 王乐,袁年财 | 11/17/13:30 | 4.2% |
V1.1.1 | 完善随机出题功能:不再重复出相同的题 | 袁年财 | 11/16/21:09 | 4.2% |
V1.1.0 | 新增随机出题功能(可能重复),显示完成题目后的总成绩 | 袁年财 | 11/16/13:36 | 5% |
V1.0.0 | 完成简单答题程序总架构 | 袁年财 | 11/16/13:00 | 5% |
总计 | 共发布21个版本 | \ | 耗时8天 | 共完成90% |
—————————————————————————————————————
链接:此链接为此次项目的课程设计报告PPT
—————————————————————————————————————
1:袁年财:
自我感悟: 在这次的项目中,我确实是收益颇丰啊!我在不断的调用、定义中加深了对函数的理解,同时也更为体会到了指针的魅力。
在敲几百行代码的过程中我意识到了结构化程序的重要性,以及宏定义的方便性。在开始任务之前老师让我们写出了任务需求表和流程图以及函数详细设计表,开始时我还觉得没有什么太大的必要性,而在开始任务的过程中,我便越发觉得老师的明智,当你在敲代码时经常会需要问接下来需要做什么,而在写出了任务需求表及其流程图之后,你会觉得任务极其的明确,丝毫不会觉得自己像一个无头苍蝇。总的来说在这次项目中是受益良多,回味无穷!
自我检讨: 在这次的项目中,我有个极大的缺点就是包揽了太多的任务,导致自己经常熬夜敲代码,丝毫没有团队意识,没有学会和队友们分担作业,这是我在担任组长这个位置的极大失责。
2:王乐:
我的体会是:刚开始时是最难的,没有思绪和目标,然后在写需求分析的时候有了一点想法,后面我在敲文件的输入输出时,总是有错误,然后回过头把书看一遍,总之:书读百遍其义自见,然后我想说的是,我们第二组最优秀!
3:杨令:
过程体会:编写这个程序时,我只做了很少一部分。但还是感觉挺难搞的。在编写过程中也参与得少,但是我感觉我们的程序还棒的。希望下次能多参与这些偏程。给自己加个油。
—————————————————————————————————————
这篇博文,只是供大家大致的参考,其中贴上的代码,是其中重要函数的代码,如果有博友对这个多功能答题程序想要更为详细的了解,或者提出宝贵的意见的话,欢迎大家评论在下方!