登录

在这个站点登录

保存我的登录记录

<<忘记密码?

还没有账号?点此注册>>

Jerry

学生成绩管理系统-MySQL版-Part8-输出数据

分享到:

本文已被浏览4803

今天期末考试结束,为了纪念发篇博文。(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;
}

 手机扫描左边的二维码,立刻将文章收入手机!
 微信扫描左边二维码,点击右上角即可分享到朋友圈!
严禁任何非授权的采集与转载,转载须经站长同意并在文章显著位置标注本文连接,站长保留追究法律责任的权利.

评论

 您需要 先登录 才可以回复.