user-0 提问: 求助贴！学了C语言程序设计大作业，能运行可是学生系统总是有误，请各位大神帮我看看怎么改呢？

回复:
user: user-1
content: 可以看一下这篇文章《C语言大作业之超市管理系统》 https://www.weupgo.cn/?p=545，有源码。

user: user-2
content: printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

user: user-0
content: 引用 2 楼 c_lanxiaofang 的回复:有点乱  你可以排好点吗 第一次发帖不是很懂 在我的vc上面看着还是好的格式发出来就是错的了 这是改了一点点后的程序呢 #include<stdio.h> #include<stdlib.h> #include <time.h> int  N;                                        //题目的数量 typedef struct  text1                          //将题目定义为结构体 {int num;									   //题号 char topic[50];								   //题目 char a[10],b[10],c[10],d[10];				   //ABCD四个选项 char rightanswer[2];						   //正确答案 }TEXT;  void teacher(TEXT text[]);                     //教师系统 void writetofile(TEXT text[],int i);		   //数据块写文件 void student(TEXT text[]);                     //学生系统 void readfromfile(int n);		   //数据块读文件 void menu();                                   //主菜单 void print(); void ent_a(); void ent_s(); FILE *fp;   void main() {   TEXT text[100]; 	int a; 	printf("\n\n\n\n\n\n\n\t\t\t欢迎进入在线考试系统！\n\n\n\n\n\n"); 	printf("\t\t\t按任意键进入主页面----->"); 	getch(); 	system("cls");         menu();                                                                         //进入菜单显示出选择系统的界面         scanf("%d",&a);         while(a)         {         switch(a)                                                                    //选择系统                 {                  case 1:printf("老师开始增加题目\n");ent_a();system("cls");teacher(text);system("cls");break;                  case 2:printf("学生开始考试\n");ent_s();system("cls");student(text);system("cls");break;                  case 3:printf("题库中的题目\n");ent_a();print();printf("\n\n按任意键返回菜单\n");getch();system("cls");break;                  default:printf("输入错误!");system("cls");menu;break;                 }               menu();               scanf("%d",&a);          }        system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t欢迎下次使用鲁川系统!\n\n\n\n\n\n\n\n\n\n"); }   void menu()                                    //友好界面菜单栏 {     printf("\t\t\t┏━━━━━━━━━━━━━━┓\n");     printf("\t\t\t┃  单项选择题标准化考试系统  ┃\n");     printf("\t\t\t┃                            ┃\n");     printf("\t\t\t┃┏━━━  功能菜单  ━━━┓┃\n");     printf("\t\t\t┃┃                        ┃┃\n");     printf("\t\t\t┃┃                        ┃┃\n");     printf("\t\t\t┃┃输入编号选择使用相应功能┃┃\n");     printf("\t\t\t┃┃                        ┃┃\n"); 	printf("\t\t\t┃┃                        ┃┃\n");     printf("\t\t\t┃┗━━━━━━━━━━━━┛┃\n");     printf("\t\t\t┃  1.【老师增加题目】        ┃\n");     printf("\t\t\t┃  2.【学生抽题开始考试】    ┃\n");     printf("\t\t\t┃  3.【查询题库中的所有题目】┃\n");     printf("\t\t\t┃  0.【退出系统】            ┃\n");     printf("\t\t\t┗━━━━━━━━━━━━━━┛\n");     printf("请选择功能:"); }  void ent_a() {     char key[10],password[10]="12345678";     int k=1;     while(k<=3) {	system("cls");     printf("\n\n\t\t\t\t请教师输入您的密码:\n");     scanf("%s",key);     if(strcmp(password,key)==0)     {         return;      }     else     {         k++; 	if(k>3)             {printf("\t\t\t\t输入密码错误三次，系统将自动退出！\n");             exit(0);} 	else         {printf("\t\t\t\t密码错误！请再次输入:\n");continue;} 	} } }    void ent_s() {     char key[10],password[10]="12345678";     int k=1;     while(k<=3) {	system("cls");     printf("\n\n\t\t\t\t请学生输入你的密码:\n");     scanf("%s",key);     if(strcmp(password,key)==0)     {         return;      }     else     {         k++; 	if(k>3)             {printf("\t\t\t\t输入密码错误三次，系统将自动退出！\n");             exit(0);} 	else         {printf("\t\t\t\t密码错误！请再次输入:\n");continue;} 	} } }    void teacher(TEXT text[])                                                                        /*教师系统*/ { 	int  i; 	fp=fopen("C:\danxuanti.txt","a+"); 	printf("\n\n\n\n\t\t\t请老师在此题库中输入题目：\n"); 	for(i=0;i<100;i++) 	{ 		printf("输入题目(end结束):\n");                                                    /*输入题目信息*/ 		scanf("%s",text[i].topic); 		if(strcmp(text[i].topic,"end")==0)                                                /*判断是否结束文件*/ 		{ 			fclose(fp); 			return; 		} 		printf("输入答案A：\n");                                                            /*输入题目答案以及正确答案*/ 		scanf("%s",text[i].a); 		printf("输入答案B：\n"); 		scanf("%s",text[i].b); 		printf("输入答案C：\n"); 		scanf("%s",text[i].c); 		printf("输入答案D：\n"); 		scanf("%s",text[i].d); 		printf("输入正确答案(请输入A、B、C、D):\n"); 		scanf("%s",text[i].rightanswer); 		N++; 		fprintf(fp,"%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",N,text[i].topic,text[i].a,text[i].b,text[i].c,text[i].d,text[i].rightanswer); 	}                                                                                    /*将题目的信息存放在文件中*/ 	fclose(fp); }    void student(TEXT text[])                                  //学生系统 { 	int n; 	if((fp=fopen("C:\danxuanti.txt","r"))==NULL) 	{ 		N=0; 		printf("该题库无题目请先添加题目，按任意键返回!"); 		getch(); 		system("cls"); 		return; 	} 	printf("请输入答题数目(格式为正整数):[ ]\b\b"); 	scanf("%d",&n); 	readfromfile(n); 	fclose(fp); }  void readfromfile(int n) {	 	char answer[2]; 	int count=0,i,idx; 	double c; 	FILE *fp; 	int number; 	if(n>100) 		return; 	srand((unsigned) time(NULL)); //用时间做种，每次产生随机数不一样 	number = rand() % (N+1);  //产生0-100的随机数 	if((fp=fopen("danxuanti.txt","r"))==NULL) 	{ 		printf("failure to open the txt!"); 		exit(0); 	} 	for(i=0;i<n&&number<100;i++,number++) 	{	 		fscanf(fp,"%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text[idx].topic,text[idx].a,text[idx].b,text[idx].c,text[idx].d,text[idx].rightanswer); 		printf("%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text[idx].topic,text[idx].a,text[idx].b,text[idx].c,text[idx].d,text[idx].rightanswer); 	    printf("请输入你的答案:\n"); 	    scanf("%s",answer); 		if(strcmp(text[idx].rightanswer,answer)==0) 		{ 			printf("恭喜你回答正确！"); 			count++; 		} 		else printf("回答错误！正确答案是：%s",text[idx].rightanswer); 	} 	c=count*1.0/n; 	printf("你的正确率为%f",c); 	fclose(fp); 	getch(); }   void print() { 	FILE *fp = fopen("C:\danxuanti.txt", "r"); 	int c; 	while((c=fgetc(fp))!=EOF) putchar(c); 	printf("以上为题库中的题目\n");  }

user: user-0
content: 引用 3 楼 cfjtaishan 的回复:void ent_a() {     char key[10], password[10]="12345678";     int k=1;     while(k<=3)     {   system("cls");         printf("\n\n\t\t\t\t请教师输入您的密码:\n");         scanf("%s",key);         if(strcmp(password,key)==0)         {             //return 0;             return;         }         else         {             k++;             if(k>3)             {                 printf("\t\t\t\t输入密码错误三次，系统将自动退出！\n");                 exit(0);             }             else             {                 printf("\t\t\t\t密码错误！请再次输入:\n");                 continue;             }         }     } } 函数定义为void返回值，因此不能return 0;把0去掉即可； 同理ent_s也是同样的问题；  void teacher(TEXT text[])                                                                        /*教师系统*/ {     int  i;     fp=fopen("C:\danxuanti.txt","a+");     if (!fp)         exit(0);     printf("\n\n\n\n\t\t\t请老师在此题库中输入题目：\n");     //for(i=0;i<1000;i++)     for(i=0;i<100;i++)     {         printf("输入题目(end结束):\n");                                                    /*输入题目信息*/         scanf("%s",text[i].topic);         if(strcmp(text[i].topic,"end")==0)                                                /*判断是否结束文件*/         {             fclose(fp);             //return 0;             return;         }         printf("输入答案A：\n");                                                            /*输入题目答案以及正确答案*/         scanf("%s",text[i].a);         printf("输入答案B：\n");         scanf("%s",text[i].b);         printf("输入答案C：\n");         scanf("%s",text[i].c);         printf("输入答案D：\n");         scanf("%s",text[i].d);         printf("输入正确答案(请输入A、B、C、D):\n");         scanf("%s",text[i].rightanswer);         N++;         fprintf(fp,"%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",N,text[i].topic,text[i].a,text[i].b,text[i].c,text[i].d,text[i].rightanswer);     }                                                                                    /*将题目的信息存放在文件中*/     fclose(fp); } 参考一下这个，一个问题是函数是void返回值，因此return 0;是和定义矛盾的。解决方法也是去掉0； 文件打开之后需要判断fp，保证文件是打开成功的。main函数里定义的text是100长度，因此这儿的循环不能超过100，否则会导致数组越界；  void student(TEXT text[])                                  //学生系统 {     int n;     //if(fp=fopen("C:\danxuanti.txt","r")==NULL)     if((fp=fopen("C:\danxuanti.txt","r"))==NULL)     {         N=0;         printf("该题库无题目请先添加题目，按任意键返回!");         getch();         system("cls");         //return 0;         return;     }     printf("请输入答题数目(格式为正整数):[ ]\b\b");     scanf("%d",&n);     readfromfile(n); }  如上改动；同样的问题，定义的是void，却返回0；另一个问题，注意if里表达式的优先级，若这样写: if(fp=fopen("C:\danxuanti.txt","r")==NULL) 优先级是fopen的返回值与NULL比较，然后将比较之后的结果赋值给fp; 另外一个问题，该函数内打开了文件却没有关闭；  void readfromfile(TEXT text[], int n) {     if (n > 100)         return;     char answer[2];     //int count,i;     int count = 0, i, idx;     double c;     FILE *fp;     //TEXT text;     int number;     srand((unsigned) time(NULL)); //用时间做种，每次产生随机数不一样     number = rand() % (N+1);  //产生0-100的随机数     if((fp=fopen("danxuanti.txt","r"))==NULL)     {         printf("failure to open the txt!");         exit(0);     }     //for(i=0;i < n;i++,number++)     for(i=0;i < n && number < 100;i++,number++)     {         //fseek(fp,(number-1)*sizeof(struct text1),SEEK_SET);         //fread(&text,sizeof(struct text1),1,fp);         idx = number-1;         //printf("%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text.topic,text.a,text.b,text.c,text.d,text.rightanswer);         printf("%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text[idx].topic,text[idx].a,text[idx].b,text[idx].c,text[idx].d,text[idx].rightanswer);         printf("请输入你的答案:\n");         scanf("%s",answer);         if(strcmp(text[idx].rightanswer,answer)==0)         {             printf("恭喜你回答正确！");             count++;         }         else             printf("回答错误！正确答案是：%s",text[idx].rightanswer);     }     //c=count/n;     c=count * 1.0 / n;     printf("你的正确率为%f",c);     fclose(fp);     getch(); }  对比参考一下吧  cout未初始化，count/n计算的是整型，要转成double类型，需要count * 1.0 / n； 上面写入文件是用fprintf，但是读的时候却用fread，格式不对称，自然读到的数据也不一定完全和写入的一样。 与其去读文件，不如直接使用上面输入的text； 注意输入的n不要超过100，否则会导致数组越界。  基础还需要加强学习，代码比较乱。首先自己要解决编译出现的错误；谢谢谢谢啦，刚刚按照您的方法又改了改，其他地方都懂了，可是用vc++编译出来还是学生系统的readfromfile函数编辑出现错误了。 我的想法是将文件按照结构体的方式输入文件中，然后再将文件中的指针随机指向一个结构体然后输出想要抽的几道题出来。 第一次写这么长的程序所以写的有点乱乱的，网上也借鉴了很多的方法可就是没有写出来的。

user: user-3
content: void ent_a() {     char key[10], password[10]="12345678";     int k=1;     while(k<=3)     {   system("cls");         printf("\n\n\t\t\t\t请教师输入您的密码:\n");         scanf("%s",key);         if(strcmp(password,key)==0)         {             //return 0;             return;         }         else         {             k++;             if(k>3)             {                 printf("\t\t\t\t输入密码错误三次，系统将自动退出！\n");                 exit(0);             }             else             {                 printf("\t\t\t\t密码错误！请再次输入:\n");                 continue;             }         }     } } 函数定义为void返回值，因此不能return 0;把0去掉即可； 同理ent_s也是同样的问题；  void teacher(TEXT text[])                                                                        /*教师系统*/ {     int  i;     fp=fopen("C:\danxuanti.txt","a+");     if (!fp)         exit(0);     printf("\n\n\n\n\t\t\t请老师在此题库中输入题目：\n");     //for(i=0;i<1000;i++)     for(i=0;i<100;i++)     {         printf("输入题目(end结束):\n");                                                    /*输入题目信息*/         scanf("%s",text[i].topic);         if(strcmp(text[i].topic,"end")==0)                                                /*判断是否结束文件*/         {             fclose(fp);             //return 0;             return;         }         printf("输入答案A：\n");                                                            /*输入题目答案以及正确答案*/         scanf("%s",text[i].a);         printf("输入答案B：\n");         scanf("%s",text[i].b);         printf("输入答案C：\n");         scanf("%s",text[i].c);         printf("输入答案D：\n");         scanf("%s",text[i].d);         printf("输入正确答案(请输入A、B、C、D):\n");         scanf("%s",text[i].rightanswer);         N++;         fprintf(fp,"%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",N,text[i].topic,text[i].a,text[i].b,text[i].c,text[i].d,text[i].rightanswer);     }                                                                                    /*将题目的信息存放在文件中*/     fclose(fp); } 参考一下这个，一个问题是函数是void返回值，因此return 0;是和定义矛盾的。解决方法也是去掉0； 文件打开之后需要判断fp，保证文件是打开成功的。main函数里定义的text是100长度，因此这儿的循环不能超过100，否则会导致数组越界；  void student(TEXT text[])                                  //学生系统 {     int n;     //if(fp=fopen("C:\danxuanti.txt","r")==NULL)     if((fp=fopen("C:\danxuanti.txt","r"))==NULL)     {         N=0;         printf("该题库无题目请先添加题目，按任意键返回!");         getch();         system("cls");         //return 0;         return;     }     printf("请输入答题数目(格式为正整数):[ ]\b\b");     scanf("%d",&n);     readfromfile(n); }  如上改动；同样的问题，定义的是void，却返回0；另一个问题，注意if里表达式的优先级，若这样写: if(fp=fopen("C:\danxuanti.txt","r")==NULL) 优先级是fopen的返回值与NULL比较，然后将比较之后的结果赋值给fp; 另外一个问题，该函数内打开了文件却没有关闭；  void readfromfile(TEXT text[], int n) {     if (n > 100)         return;     char answer[2];     //int count,i;     int count = 0, i, idx;     double c;     FILE *fp;     //TEXT text;     int number;     srand((unsigned) time(NULL)); //用时间做种，每次产生随机数不一样     number = rand() % (N+1);  //产生0-100的随机数     if((fp=fopen("danxuanti.txt","r"))==NULL)     {         printf("failure to open the txt!");         exit(0);     }     //for(i=0;i < n;i++,number++)     for(i=0;i < n && number < 100;i++,number++)     {         //fseek(fp,(number-1)*sizeof(struct text1),SEEK_SET);         //fread(&text,sizeof(struct text1),1,fp);         idx = number-1;         //printf("%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text.topic,text.a,text.b,text.c,text.d,text.rightanswer);         printf("%d.%s\n\nA.%s\nB.%s\nC.%s\nD.%s\nrightanswer：%s\n\n",i+1,text[idx].topic,text[idx].a,text[idx].b,text[idx].c,text[idx].d,text[idx].rightanswer);         printf("请输入你的答案:\n");         scanf("%s",answer);         if(strcmp(text[idx].rightanswer,answer)==0)         {             printf("恭喜你回答正确！");             count++;         }         else             printf("回答错误！正确答案是：%s",text[idx].rightanswer);     }     //c=count/n;     c=count * 1.0 / n;     printf("你的正确率为%f",c);     fclose(fp);     getch(); }  对比参考一下吧  cout未初始化，count/n计算的是整型，要转成double类型，需要count * 1.0 / n； 上面写入文件是用fprintf，但是读的时候却用fread，格式不对称，自然读到的数据也不一定完全和写入的一样。 与其去读文件，不如直接使用上面输入的text； 注意输入的n不要超过100，否则会导致数组越界。  基础还需要加强学习，代码比较乱。首先自己要解决编译出现的错误；

user: user-4
content: 有点乱  你可以排好点吗

user: user-0
content: 基本的要求是这些 单项选择题测试系统 1、 用文件保存试题库，每个试题包括题干、4 个备选答案、标准答案； 2、 试题输入，增加试题到试题库中； 3、 试题抽取，每次从试题库中抽出 n 道题（n 由键盘输入） ； 4、 答题，用户输入自己的答案； 5、 自动判卷，系统可根据用户答案与标准答案的对比实现判卷并给出成绩。