学生成绩管理系统-MySQL版-Part8-输出数据
本文已被浏览4942次
今天期末考试结束,为了纪念发篇博文。(shen me gui)
上次写到了第七部分的导入数据,作为一个软件,IO是成对出现的,有I(Input)就要有O(Output),本篇文章将会介绍一下对于输出的问题,不管是输出到屏幕上,亦或是输出至文件中,都在本次的讨论范围内。
一、输出到屏幕
输出到屏幕上的是比较简单的一个部分,直接用MySQL的SELECT查询语句即可,把数据表所有数据全部读出来,随后再逐行打印出数据即可。
二、输出到文件
这里的文件指的是csv和sql文件。
对于CSV文件来说,本身的文件结构并不是很复杂,直接把在屏幕输出时候输出的制表符t替换成英文半角逗号即可,换行不变。
对于SQL文件就稍微的复杂些,因为要涉及到将表的结构和数据转化为SQL语句,同时也要符合上一节叙述到的SQL文件的注释类型,具体如何获取表结构和数据并构成SQL文件,就直接看代码吧。
下面是对于输出数据
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <windows.h> #include <mysql.h> #include <conio.h> //引入有用没用的头文件(傻傻的分不清) extern MYSQL mysql; extern MYSQL_RES *result; extern MYSQL_ROW row; extern MYSQL_FIELD *field; //继承变量 char Host[15]; char Port[8]; char Username[10]; char Password[20]; char DB[10]; //并没有卵用的几个函数,直接粘来的 //函数原型列表 int LoadSettings(); int Install(int mode); int Connect_DB(); int Get_Score_Table(int Index,char* str); int Get_Table_Field(const char *table,int Index,char *Fieldname); int Show_Table(const char *tablename,const char *title,const char *sqlplus); void ChangeColorScreen(const char* color); void ChangeWindowSize(int Width,int Height); void Pause(int mode); void CS(); void Ring(); void Login(); void Exit(); void ChangeWindowSize(int Width,int Height); void ChangeWindowTitle(const char* title); void strrpl(char* pDstOut, char* pSrcIn, const char* pSrcRpl, const char* pDstRpl); int Sum_ints(int number); int Export_Score(); int Export_Score_ToScreen(int TableIndex); int Export_Score_ChoseTarget(int tableselect); int Export_Score_ToCSV(int Index); int Export_Score_ToSQL(int Index); int Get_Score_Table(int Index,char* str); int Core(); //功能入口函数 int Export_Score() { char sql[100],temp[100],select[10]; int lines,item=1,i; ChangeWindowTitle("导出数据"); //获取所有数据表 sprintf(sql,"Show Tables like 'scm_class_%%'"); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); lines=mysql_num_rows(result); ChangeWindowSize(40,lines+14); printf("╔═════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ 导出成绩单 ║n"); printf("╟─────────────────╢n"); //注意:如果想要导出数据,必须要有数据才行,故在之前判断一下 if(lines==0) { printf("║ 当前数据库中没有可用成绩单! ║n"); printf("║ 按任意键返回主菜单! ║n"); printf("╟─────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════╝n>"); Pause(0); return 0; } //在有数据情况下,打印成绩单列表 printf("║ 请选择希望导出的成绩单: ║n"); while((row=mysql_fetch_row(result))) { strrpl(temp,row[0],"scm_class_",""); printf("║ [%d] %s",item,temp); for(i=strlen(temp)+Sum_ints(item)-1; i<28; i++) { printf(" "); } printf("║n"); item++; } printf("╟─────────────────╢n"); printf("║ [B] 返回上级菜单 ║n"); printf("╟─────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════╝n>"); fflush(stdin); //获取输入 gets(select); //根据选择进行跳转函数 if(atoi(select)>0&&atoi(select)<item) { Export_Score_ChoseTarget(atoi(select)); } else if(strcasecmp(select,"B")==0) { return 0; } else { printf("请输入有效数据!"); Sleep(1000); } Export_Score(); return 0; } //选择导出目标 int Export_Score_ChoseTarget(int tableselect) { char select,tablename[20],temp[30]; CS(); Get_Score_Table(tableselect,tablename); strrpl(tablename,tablename,"scm_class_",""); sprintf(temp,"输出:%s",tablename); ChangeWindowTitle(temp); printf("╔═════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ 输出成绩单 ║n"); printf("╟─────────────────╢n"); printf("║ 请选择导出目标: ║n"); printf("║ [1] 打印至屏幕 ║n"); printf("║ [2] 导出到*.sql文件 ║n"); printf("║ [3] 导出到*.csv文件 ║n"); printf("╟─────────────────╢n"); printf("║ [B] 返回主菜单 ║n"); printf("╟─────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════╝n"); fflush(stdin); select=getch(); switch(select) { case '1': Export_Score_ToScreen(tableselect); break; case '2': Export_Score_ToSQL(tableselect); break; case '3': Export_Score_ToCSV(tableselect); break; case 'b': case 'B': Core(); break; default: Export_Score_ChoseTarget(tableselect); break; } return 0; } //打印至屏幕 int Export_Score_ToScreen(int TableIndex) { char Table[20],sql[100],FieldName[20]; char addsql[50]; int i,j,select; Get_Score_Table(TableIndex,Table); ChangeWindowTitle("输出顺序"); CS(); sprintf(sql,"SELECT * From %s",Table); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); ChangeWindowSize(40,11+mysql_num_fields(result)); //考虑到一个升降序的问题,在输出前询问用户 printf("╔═════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ 导出成绩单 ║n"); printf("╟─────────────────╢n"); printf("║ 请选择输出排序索引: ║n"); printf("║ [1] 按照导入数据时的顺序 ║n"); field=mysql_fetch_field(result); //然而只是在列举所有的字段 for(i=1; i<mysql_num_fields(result); i++) { field=mysql_fetch_field(result); printf("║ [%d] %s",i+1,field->name); for(j=(field->name_length)*2+Sum_ints(i+1)+4; j<38; j++) { printf(" "); } printf("║n"); } printf("╟─────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════╝n>"); Index_Error: fflush(stdin); scanf("%d",&select); //获取输入 if(select<0||select>mysql_num_fields(result)) { printf("选项无效,请重试!n>"); goto Index_Error; } //根据字段序号获取字段 Get_Table_Field(Table,select,FieldName); CS(); ChangeWindowSize(63,13); ChangeWindowTitle("排序法则"); printf("╔═════════════════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ Mysql版 ║n"); printf("╟─────────────────────────────╢n"); printf("║ 请选择您希望的输出方式: ║n" "║ [1]升序(从小到大,字典顺序) ║" "║ [2]降序(从大到小,逆字典顺序) ║"); printf("╟─────────────────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════════════════╝n>"); Desc_Asc_ERR: fflush(stdin); scanf("%d",&select); if(strcmp(FieldName,"姓名")==0) { if(select==1) { //此处是针对于姓名升降序的排列,还没搞懂,先空着 } else if(select==2) { //此处是针对于姓名升降序的排列,还没搞懂,先空着 } else { goto Desc_Asc_ERR; } } else { //其他全是分数的好说了,在后面加个排序条件即可 if(select==1) { sprintf(addsql,"order by %s asc",FieldName); } else if(select==2) { sprintf(addsql,"order by %s desc",FieldName); } else { goto Desc_Asc_ERR; } } Show_Table(Table,"输出到屏幕",addsql); Pause(1); return 0; } //输出至CSV int Export_Score_ToCSV(int Index) { char Tablename[100]; char temp[100],FileTarget[200]; char Location[100]; char sql[1000]; char choice; FILE *FilePointer; int i,j; CS(); Get_Score_Table(Index,Tablename); ChangeWindowSize(55,10); //首先需要一个存放目录 printf("请输入输出文件存放目录(可直接把文件夹拖进来,最后不加\)n>"); FileLocation: fflush(stdin); gets(Location); if(strcmp(Location,"back")==0) return 0; strrpl(temp,Tablename,"scm_class_",""); sprintf(FileTarget,"%s\%s.csv",Location,temp); //以写入方式打开文件 if((FilePointer=fopen(FileTarget,"w"))==NULL) { //失败提示后调回 printf("创建%s失败,请确定此目录存在并可写!n请重新输入n返回请输入back>",temp); goto FileLocation; } else { //准备导出数据 sprintf(sql,"SELECT * From %s",Tablename); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); printf("正在导出科目数据...n"); field=mysql_fetch_field(result); //将科目写入csv文件 for(i=1,field=mysql_fetch_field(result); i<mysql_num_fields(result); i++,field=mysql_fetch_field(result)) { fprintf(FilePointer,"%s",field->name); if(i+1==mysql_num_fields(result)) { fprintf(FilePointer,"n"); } else { fprintf(FilePointer,","); } } printf("正在导出数据...n"); //将具体成绩数据写入csv文件 for(i=0,row=mysql_fetch_row(result); i<mysql_num_rows(result); i++,row=mysql_fetch_row(result)) { for(j=1; j<mysql_num_fields(result); j++) { fprintf(FilePointer,"%s",row[j]); if(j+1==mysql_num_fields(result)) { fprintf(FilePointer,"n"); } else { fprintf(FilePointer,","); } } } fclose(FilePointer); CS(); printf("导出成功!n是否打开导出文件?n[Y/N]"); ReChoice: //最后问一下要不要打开文件 choice=getch(); switch(choice) { case 'Y': case 'y': sprintf(temp,"start %s",FileTarget); system(temp); break; case 'N': case 'n': break; default: printf("n请输入正确的内容[Y/N]:"); goto ReChoice; } } return 0; } int Export_Score_ToSQL(int Index) { char TableName[100],sql[1000]; char Location[1000],temp[100],selected; char Folder[1000]; int FieldsSum=0,i,j,Prikey=-1; MYSQL_ROW Columns[1000]; FILE *SQLER; Get_Score_Table(Index,TableName); CS(); ChangeWindowTitle("导出到SQL文件"); ChangeWindowSize(63,12); printf("╔═════════════════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ 基于MySQL ║n"); printf("╟─────────────────────────────╢n"); printf("║ 请输入导出的SQL文件的存放目录(或者直接拖入一个文件夹,最后║n" "║ 不加\) ║n"); printf("╟─────────────────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════════════════╝n>"); Get_SQL_Location: //和上面一样要获取存放目录并以写入方式打开文件 gets(Folder); sprintf(Location,"%s\%s.sql",Folder,TableName); if((SQLER=fopen(Location,"w"))==NULL) { printf("%s不可写,请重新输入>",Location); goto Get_SQL_Location; } //准备数据表的各个字段属性 sprintf(sql,"SHOW columns from %s",TableName); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); for(FieldsSum=0; FieldsSum<mysql_num_rows(result); FieldsSum++) { Columns[FieldsSum]=mysql_fetch_row(result); } //刚刚开始写几行注释 fprintf(SQLER,"-- 学生成绩管理系统专用导出文件n"); fprintf(SQLER,"-- 基于酷炫狂拽的MySQL数据库n"); fprintf(SQLER,"-- Host:%sn",Host); strrpl(temp,TableName,"scm_class_",""); fprintf(SQLER,"-- 班级:%snn",temp); fprintf(SQLER,"-- n-- 数据库:%sn-- ",DB); fprintf(SQLER,"-- -------------------n"); fprintf(SQLER,"-- 表名:%sn",TableName); fprintf(SQLER,"-- nn-- 表的结构n"); //判断表的存在并创建表格 fprintf(SQLER,"CREATE TABLE IF NOT EXISTS `%s` (n",TableName); //转储表格各个项目的类型 for(i=0; i<FieldsSum; i++) { fprintf(SQLER," `%s` %s NOT NULL %s",Columns[i][0],Columns[i][1],Columns[i][5]); if(i+1!=FieldsSum) { fprintf(SQLER,",n"); } if(Prikey==-1&&strcasecmp(Columns[i][3],"PRI")) Prikey=i; } //搞到那个主键的属性一般是ID if(Prikey!=-1) fprintf(SQLER,",nPRIMARY KEY(`%s`)n",Columns[Prikey][0]); sprintf(sql,"SELECT * From %s",TableName); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); fprintf(SQLER,") ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=%d;nn",(int)(mysql_num_rows(result)+1)); //执行数据插入前先清空数据表 fprintf(SQLER,"--清空数据n"); fprintf(SQLER,"TRUNCATE TABLE `%s`;",TableName); fprintf(SQLER,"INSERT INTO `%s` (",TableName); //开始写入数据 for(i=0; i<FieldsSum; i++) { fprintf(SQLER,"`%s`",Columns[i][0]); if(i+1!=FieldsSum) { fprintf(SQLER,", "); } else { fprintf(SQLER,") VALUESn"); } } //写入数据 for(i=0; i<mysql_num_rows(result); i++) { row=mysql_fetch_row(result); fprintf(SQLER,"("); for(j=0; j<FieldsSum; j++) { fprintf(SQLER,"`%s`",row[j]); if(j+1!=FieldsSum) { fprintf(SQLER,","); } else { if(i+1!=mysql_num_rows(result)) { fprintf(SQLER,"),n"); } else { fprintf(SQLER,");"); } } } } //成功结束并关闭文件 fclose(SQLER); ToSQL_Folder_Err: CS(); printf("导出成功!是否打开对于文件目录[Y/N]>"); selected=getch(); switch(selected) { case 'Y': case 'y': sprintf(temp,"explorer %s",Folder); system(temp); break; case 'N': case 'n': break; default: Ring(); goto ToSQL_Folder_Err; } return 0; }
三、查询数据
这里有一个问题是查询。查询用到的也是SELECT语句,由于之前在百度上并没有找到可以全表搜索的语句,所以就用了一堆的OR连接各个判断语句,导致此处执行的mysql语句非常的长,虽然目前还没有发生溢出的情况,但是这个Bug是有可能出现的。写完程序后反过来写博客的时候发现可以直接用若干个查询来查找,然后将所有查询到的数据存到一个总的数组中,去除重复项目后输出即可(然而并没有这么做)。
//引入头文件 #include <stdio.h> #include <windows.h> #include <mysql.h> #include <string.h> //继承变量 extern MYSQL mysql; extern MYSQL_RES *result; extern MYSQL_ROW row; extern MYSQL_FIELD *field; //声明一些函数原型 void ChangeColorScreen(const char *color); void ChangeWindowSize(int Width,int Height); void ChangeWindowTitle(const char *title); void CS(); void Pause(int mode); void JR_SetColor(int textcolor,int bgcolor); void strrpl(char* pDstOut, char* pSrcIn, const char* pSrcRpl, const char* pDstRpl); int Query_Score_Show(char *KeyWord); //查询主入口 int Query_Score() { char select[20]; ChangeWindowSize(63,12); ChangeWindowTitle("成绩查询"); CS(); printf("╔═════════════════════════════╗n"); printf("║ 学生成绩管理系统 ║n"); printf("║ 基于MySQL ║n"); printf("╟─────────────────────────────╢n"); printf("║ 请输入关键字: ║n"); printf("║ 关键字可以是一个同学的名字,一个分数.输入exit返回主菜单 ║n"); printf("╟─────────────────────────────╢n"); printf("║ JerrySoft Copyright. ║n"); printf("╚═════════════════════════════╝n>"); fflush(stdin); scanf("%s",select); if(strcasecmp(select,"exit")==0) { return 0; } Query_Score_Show(select); Query_Score(); return 0; } //查询主程序 int Query_Score_Show(char *KeyWord) { char sql[1000],sql2[1000]; char tables[100][20],classname[100],title[20]; int tabs=0; int i,j; sprintf(sql,"Show Tables Like 'scm_class_%%'"); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); //这里把所有的表格都先轮询一遍,计划在所有表格中查找数据 while((row=mysql_fetch_row(result))) { sprintf(tables[tabs],row[0]); tabs++; } for(i=0; i<tabs; i++) { //查询列表 sprintf(sql,"show columns from %s",tables[i]); mysql_query(&mysql,sql); //构建查询指定列 result=mysql_store_result(&mysql); sprintf(sql,"SELECT "); row=mysql_fetch_row(result); memset(sql2,0,1000); for(j=1; j<mysql_num_rows(result); j++) { row=mysql_fetch_row(result); //这就是要去写那个长的不得了的判断语句 if(j+1!=mysql_num_rows(result)) { sprintf(sql,"%s%s,",sql,row[0]); sprintf(sql2,"%s %s like '%s' OR",sql2,row[0],KeyWord); } else { sprintf(sql,"%s%s",sql,row[0]); sprintf(sql2,"%s %s like '%s'",sql2,row[0],KeyWord); } } //构建查询表格 sprintf(sql,"%s From %s Where %s",sql,tables[i],sql2); mysql_query(&mysql,sql); result=mysql_store_result(&mysql); if(mysql_num_rows(result)>0) { //搞到数据就输出 strrpl(classname,tables[i],"scm_class_",""); sprintf(title,"在%s中找到%d条",classname,(int)mysql_num_rows(result)); ChangeWindowSize(mysql_num_fields(result)*8+1,mysql_num_rows(result)+5); ChangeWindowTitle(title); field=mysql_fetch_field(result); JR_SetColor(10,1);//涂成绿的 //输出字段名 for(j=1; j<mysql_num_fields(result); j++) { field=mysql_fetch_field(result); printf("%st",field->name); } JR_SetColor(15,1);//恢复 printf("n"); while((row=mysql_fetch_row(result))) { for(j=1; j<mysql_num_fields(result); j++) { if(strcmp(row[j],KeyWord)==0){ //如果匹配查询字符串,用红色高亮 JR_SetColor(12,1); printf("%st",row[j]); JR_SetColor(15,1); }else{ //不匹配就原色 printf("%st",row[j]); } } printf("n"); } if(i+1!=tabs){ //对于中间表和末尾表显示不同的提示信息 printf("按任意键显示下一表格>"); }else{ printf("输出结束按任意键返回上级菜单>"); } Pause(0); } //没有就下一个表继续找 } return 0; }
评论
您需要 先登录 才可以回复.