C语言单项选择题标准化考试系统,朋友发给我的代码按照步骤一步步进行下去,后面会陷入死循环,求帮忙看看这个代码修改一下下。能不能浅浅解释一下下谢谢了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define File "data.txt"//试题文件
#define File1 "test.txt"//抽取的试卷文件
typedef struct QUES
{
int id; //编号
char body[500]; //题干
char A[100]; //选项A
char B[100]; //选项B
char C[100]; //选项C
char D[100]; //选项D
int chapter; //章节
int answer; //标准答案,1-A,2-B,3-C,4-D
int score; //分值
struct QUES* next;
}QUES;
struct QUES* test;
struct QUES* selectTest;
int QuesNum =0;//试题数目
//显示单个试题
void show(struct QUES* ques)
{
printf("题号:%d,章节号:%d,标准答案:%s,分值:%d\n",ques->id,ques->chapter,(ques->answer==1?"A":(ques->answer==2?"B":ques->answer==3?"C":"D")),ques->score);
printf("%s\n%s\n%s\n%s\n%s\n", ques->body, ques->A, ques->B, ques->C, ques->D);
}
//显示全部试题
void showAll(){
if(QuesNum == 0){
printf("暂无试题\n");
return;
}
struct QUES* p = test->next;
while(p!=NULL){
show(p);
p = p->next;
}
}
//读取试题
void readQues(){
FILE *fp;
if ((fp = fopen(File, "r")) == NULL)
{
printf("Error! opening file");
// 文件指针返回 NULL 则退出
return;
}
struct QUES* list = test;
while(!feof(fp)){
if (fgetc(fp) != EOF)
{
struct QUES* info = (QUES*)malloc(sizeof(QUES));
fscanf(fp,"%d %d %d %d\n",&info->id,&info->chapter,&info->answer,&info->score);
fscanf(fp,"%[^\n]", info->body);
fgetc(fp);//获取换行符,移到下一行
fscanf(fp,"%[^\n]", info->A);//获取一行,\n终止
fgetc(fp);
fscanf(fp,"%[^\n]", info->B);
fgetc(fp);
fscanf(fp,"%[^\n]", info->C);
fgetc(fp);
fscanf(fp,"%[^\n]", info->D);
info->next = list->next;
list->next = info;
list = list->next;
QuesNum ++ ;
}
}
fclose(fp);
struct QUES* p = test;
while(p->next->next){
p = p->next;
}
QuesNum --;
p->next = NULL;
return ;
}
//保存试题
void saveQues(){
FILE *fp = NULL;
struct QUES * pMove;
pMove = test->next;
fp = fopen(File,"w");
fprintf(fp, " ");
while (pMove)
{
fprintf(fp,"%d %d %d %d\n",pMove->id,pMove->chapter,pMove->answer,pMove->score);
fprintf(fp,"%s\n%s\n%s\n%s\n%s\n",pMove->body,pMove->A,pMove->B,pMove->C,pMove->D);
pMove = pMove->next;
}
fclose(fp);
}
//保存抽取的试题
void saveChioceQues(){
FILE *fp = NULL;
struct QUES * pMove;
pMove = selectTest->next;
fp = fopen(File1,"w");
fprintf(fp, " ");
while (pMove)
{
fprintf(fp,"%d %d %d %d\n",pMove->id,pMove->chapter,pMove->answer,pMove->score);
fprintf(fp,"%s\n%s\n%s\n%s\n%s\n",pMove->body,pMove->A,pMove->B,pMove->C,pMove->D);
pMove = pMove->next;
}
fclose(fp);
}
//录入试题
void addQues(){
int n,b,i;
printf("请输入要添加的试题数目:");
scanf("%d",&n);
struct QUES* list = test;
while(list->next!=NULL){
list = list->next;
}
for(i=0;i<n;i++){
struct QUES* newQuse = (QUES*)malloc(sizeof(QUES));
printf("请输入第%d个试题编号:",i+1);
scanf("%d",&newQuse->id);
printf("请输入第%d个试题章节号(整数):",i+1);
scanf("%d",&newQuse->chapter);
printf("请输入第%d个试题标准答案(1-A,2-B,3-C,4-D):",i+1);
scanf("%d",&newQuse->answer);
printf("请输入第%d个试题分值(整数):",i+1);
scanf("%d",&newQuse->score);
printf("请输入第%d个试题题干:",i+1);
scanf("%s",newQuse->body);
printf("请输入第%d个试题A选项(格式:A.123):",i+1);
scanf("%s",newQuse->A);
printf("请输入第%d个试题B选项(格式:B.123):",i+1);
scanf("%s",newQuse->B);
printf("请输入第%d个试题C选项(格式:C.123):",i+1);
scanf("%s",newQuse->C);
printf("请输入第%d个试题D选项(格式:D.123):",i+1);
scanf("%s",newQuse->D);
newQuse->next = list->next;//尾插法加入链表
list->next = newQuse;
list = list->next;
QuesNum ++ ;
printf("添加成功\n");
}
saveQues();
}
//插入试题
void insertQues(){
printf("请输入要插入的位置:");
int n,b,i;
scanf("%d",&b);
struct QUES* list = test;
for( i =0;i<b-1;i++){
if(list->next == NULL){
break;
}
list = list->next;
}
printf("请输入要添加的试题数目:");
scanf("%d",&n);
for( i=0;i<n;i++){
struct QUES* newQuse = (QUES*)malloc(sizeof(QUES));
printf("请输入第%d个试题编号:",i+1);
scanf("%d",&newQuse->id);
printf("请输入第%d个试题章节号(整数):",i+1);
scanf("%d",&newQuse->chapter);
printf("请输入第%d个试题标准答案(1-A,2-B,3-C,4-D):",i+1);
scanf("%d",&newQuse->answer);
printf("请输入第%d个试题分值(整数):",i+1);
scanf("%d",&newQuse->score);
printf("请输入第%d个试题题干:",i+1);
scanf("%s",newQuse->body);
printf("请输入第%d个试题A选项(格式:A.123):",i+1);
scanf("%s",newQuse->A);
printf("请输入第%d个试题B选项(格式:B.123):",i+1);
scanf("%s",newQuse->B);
printf("请输入第%d个试题C选项(格式:C.123):",i+1);
scanf("%s",newQuse->C);
printf("请输入第%d个试题D选项(格式:D.123):",i+1);
scanf("%s",newQuse->D);
newQuse->next = list->next;//加入链表
list->next = newQuse;
list = list->next;
QuesNum ++ ;
printf("插入成功\n");
}
saveQues();
}
//查找试题
void searchQues(){
int n;
if(QuesNum == 0){
printf("暂无试题信息\n");
return;
}
printf("请输入要查找的试题编号:");
scanf("%d",&n);
struct QUES* list = test->next;
while(list!=NULL){
if(list->id == n){
printf("查找成功:\n");
show(list);
return;
}
list = list->next;
}
printf("查找失败\n");
}
//删除试题
void deleteQues(){
int n;
if(QuesNum == 0){
printf("暂无试题信息\n");
return;
}
printf("请输入要删除的试题编号:");
scanf("%d",&n);
struct QUES* list = test;
while(list->next!=NULL){
if(list->next->id == n){
list->next = list->next->next;//删除
printf("删除成功:\n");
QuesNum --;
saveQues();
// show(list);
return;
}
list = list->next;
}
printf("删除失败\n");
}
//修改试题
void modifyQues(){
int n;
if(QuesNum == 0){
printf("暂无试题信息\n");
return;
}
printf("请输入要修改的试题编号:");
scanf("%d",&n);
struct QUES* list = test->next;
while(list!=NULL){
if(list->id == n){
printf("目前信息为:\n");
show(list);
printf("请输入修改后的试题编号:" );
scanf("%d",&list->id);
printf("请输入修改后的试题章节号(整数):" );
scanf("%d",&list->chapter);
printf("请输入修改后的试题标准答案:" );
scanf("%d",&list->answer);
printf("请输入修改后的试题分值(整数):" );
scanf("%d",&list->score);
printf("请输入修改后的试题题干:" );
scanf("%s",list->body);
printf("请输入修改后的试题A选项(格式:A.123):" );
scanf("%s",list->A);
printf("请输入修改后的试题B选项(格式:B.123):" );
scanf("%s",list->B);
printf("请输入修改后的试题C选项(格式:C.123):" );
scanf("%s",list->C);
printf("请输入修改后的试题D选项(格式:D.123):" );
scanf("%s",list->D);
printf("修改成功:\n");
show(list);
saveQues();
return;
}
list = list->next;
}
printf("修改失败\n");
}
//按章节号排序,冒泡排序
void sortQues(){
struct QUES *pb, *pf, temp;
pf = test;
if(QuesNum == 0) {//链表为空
printf("暂无试题信息\n");
return ;
}
if(QuesNum == 1) {//链表有1个节点
showAll();
return ;
}
while(pf->next != NULL) {//以pf指向的节点为基准节点
pb = pf->next;//pb从基准点的下一个节点开始
while(pb != NULL) {
if(pf->chapter > pb->chapter) {
temp = *pf;
*pf = *pb;
*pb = temp;
temp.next = pf->next;
pf->next = pb->next;
pb->next = temp.next;
}
pb = pb->next;
}
pf = pf->next;
}
showAll();
}
//抽取试题
void randomChioceQues(){
selectTest = (QUES*)malloc(sizeof(QUES));
selectTest->next = NULL;
int n,b,i,j;
printf("请输入抽取的题数:");
scanf("%d",&n);
if(n<=0 || n>QuesNum){
printf("输入数目有误\n");
return;
}
int *a = (int*)malloc(sizeof(int)*n);//生成动态一维数组
for(i=0;i<n;i++){
int c=1;
do{
c=1;
b = rand() % QuesNum;
for(j=0;j<i;j++){
if(a[j] == b){
c = 0;
break;
}
}
}while(c == 0);
a[i] = b;
//printf("抽取到%d\n",b);
struct QUES* list = test->next;
for(j =0;j<b;j++){
if(list->next == NULL){
break;
}
list = list->next;
}
struct QUES* newQuse = (QUES*)malloc(sizeof(QUES));
newQuse->id = list->id;
newQuse->chapter = list->chapter;
newQuse->answer = list->answer;
newQuse->score = list->score;
strcpy(newQuse->body,list->body);
strcpy(newQuse->A,list->A);
strcpy(newQuse->B,list->B);
strcpy(newQuse->C,list->C);
strcpy(newQuse->D,list->D);
newQuse->next = selectTest->next;//加入链表
selectTest->next = newQuse;
}
saveChioceQues();
printf("是否显示抽取题目(输入1显示):");
scanf("%d",&j);
struct QUES* p;
if(j == 1){
p = selectTest->next;
while(p!=NULL){
show(p);
p = p->next;
}
}
printf("是否答题(输入1开始答题):");
scanf("%d",&j);
if(j != 1){
return;
}
i=1;
p = selectTest->next;
int sum =0;
while(p!=NULL){
printf("第%d题:\n题目:",i);
printf("%s\n%s\n%s\n%s\n%s\n", p->body, p->A, p->B, p->C, p->D);
printf("请输入你的选择(1-A,2-B,3-C,4-D):");
scanf("%d",&j);
if(j == p->answer){
sum += p->score;
printf("回答正确\n\n");
}else{
printf("回答错误\n\n");
}
p = p->next;
i++;
}
printf("得分:%d\n",sum);
}
int main() {
setbuf(stdout, 0);
srand((unsigned)time(NULL));//随机数种子
test = (QUES*)malloc(sizeof(QUES));
test->next = NULL;
readQues();
//showAll();
while(1){
int input;
setbuf(stdout, 0);
printf("**********************************\n");
printf("1.录入试题\n");
printf("2.显示全部试题\n");
printf("3.插入试题\n");
printf("4.查找试题\n");
printf("5.删除试题\n");
printf("6.修改试题\n");
printf("7.按章节号排序\n");
printf("8.试题抽取\n");
printf("9.答题\n");
printf("0.返回上一级\n");
printf("**********************************\n");
scanf("%d",&input);
switch (input)
{
case 1:
addQues();
break;
case 2:
showAll();
break;
case 3:
insertQues();
break;
case 4:
searchQues();
break;
case 5:
deleteQues();
break;
case 6:
modifyQues();
break;
case 7:
sortQues();
break;
case 8:
randomChioceQues();
break;
case 9:
randomChioceQues();
break;
case 0:
printf("bye ~ \n");
return 0;
break;
default:
printf("您输入的标号有误!!\n");
break;
}
}
return 0;
}
什么状态下,会出现死循环?我试了下,没发现问题。