首先规划一下
一步一步的来做
数据库的表 做两个
一个是学生的信息表 一个是学生的成绩表
通过学号关联
需要做的是 对学生基本信息进行管理
包括查询 删除 修改 添加(添加 只需要添加一条记录)
开始的数据库 你可以 手动写入数据库表里面
另外对成绩可以进行统计 比如排序
总分 平均分
对某门课可以进行统计
比如某门课 的平均分 每个分数段的人数
先整理一下看看要做哪些内容 这些内容如何做 定一个计划
然后 一步一步来实施
我觉得快的话 1周可以完成
分三步做 :1 完成命令行的实现 2. 完成数据库 3.测试
但是肯定要规划
分成那些文件
文件的命名
要去想 和 思考
关键是如何排布 和 整合
这个非常重要
1、首先建一个文件夹stuinfo,里面分几个模块进行,分别为database,readconfig,readlines,writelogfile几个文件夹,然后分别进行程序
①先从最简单的模块入手(个人是这样操作的)
writelogfile文件下面分为stu_writelog.c stu_writelog.h makefile stu_logfile.log
stu_logfile.log是记录用户操作的日志文件,可先建成空文件
stu_writelog.h
#ifndef _STU_WRITELOG_H #define _STU_WRITELOG_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #include<stdarg.h> void write_logfile(const char *fmt,...); #endif
stu_writelog.c
#include "stu_writelog.h" void write_logfile(const char *fmt,...) { FILE *fp; char buffer[512]; char *p; time_t t; va_list ap; va_start(ap,fmt); vsprintf(buffer,fmt,ap); va_end(ap); if((fp=fopen("./writelogfile/stu_logfile.log","a+"))==NULL) { printf("open logfile failed\n"); exit(0); } time(&t); p=ctime(&t); p[strlen(p)-1]='\0'; fprintf(fp,"[%s] %s \n",p,buffer); fclose(fp); }
makefile
CC = gcc OBJS = $(wildcard *.c) TARGET = libstuwritelog.so all: $(CC) $(OBJS) -fPIC -shared -o $(TARGET) mv ./$(TARGET) /lib clean: rm -rf *.o $(TARGET)
②再就是读取配置文件readconfig
分为四个文件stuconfig.cfg stu_readconf.c stu_readconf.h makefile
stuconfig.cfg这个可以自己定义
比如:
host = localhost username = root password = 111111 database = studb
stu_readconf.h
#ifndef _STU_READCONF_H #define _STU_READCONF_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<mysql/mysql.h> #define N 512 #define LEN sizeof(struct node) struct node *readconf(char const *file); char *del(char *str); char *dupstr(char *s); int judgepasswd(char *user,char *pwd); char host[20]; char username[20]; char password[20]; char database[20]; struct node { char name[20]; char value[20]; struct node *next; }; #endif
stu_readconf.c
#include "stu_readconf.h" struct node *readconf(char const *file) { FILE *fp; struct node *head; struct node *p,*q; char buffer[N]; char *str1,*str2; if((fp=fopen(file,"r"))==NULL) { printf("Open configure file failed\n"); } p=(struct node *)malloc(LEN); head=p; while(fgets(buffer,N,fp)!=NULL) { if(str1=strchr(buffer,'#')) { *str1='\0'; } if(str2=strchr(buffer,'=')) { *str2='\0'; str2++; } str1=del(buffer); str2=del(str2); q=(struct node *)malloc(LEN); strcpy(q->name,dupstr(str1)); strcpy(q->value,dupstr(str2)); p->next=q; p=q; } p->next=NULL; fclose(fp); head=head->next; return(head); } int judgepasswd(char *user,char *pwd) { struct node *p; p=readconf("./readconfig/stuconfig.cfg"); while(p) { if(strcmp("host",p->name)==0) { strcpy(host,p->value); } else if(strcmp("username",p->name)==0) { strcpy(username,p->value); } else if(strcmp("password",p->name)==0) { strcpy(password,p->value); } else if(strcmp("database",p->name)==0) { strcpy(database,p->value); } p=p->next; } if(strcmp(user,username)==0) { if(strcmp(pwd,password)==0) return 1; printf("the password is wrong!\n"); return 0; } printf("not exist the user!\n"); return 0; } char *del(char *str) { char *dest; while(*str==' ') { str++; } if(dest=strchr(str,' ')) { *dest='\0'; } if(dest=strchr(str,'\n')) { *dest='\0'; } return(str); } char *dupstr(char *s) { char *r; r=(char *)malloc(strlen(s)+1); strcpy(r,s); return(r); }
makefile
CC = gcc OBJS = $(wildcard *.c) TARGET = libstureadconf.so all: $(CC) $(OBJS) -fPIC -shared -o $(TARGET) mv ./$(TARGET) /lib clean: rm -rf *.o $(TARGET)
③再就是数据库模块database
分别为 stu_database.c stu_database.h makefile
stu_database.h
#ifndef _STU_DATABASE_H #define _STU_DATABASE_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include <getopt.h> #include "../readconfig/stu_readconf.h" #include<mysql/mysql.h> char host[20]; char username[20]; char password[20]; char database[20]; static int n=0; MYSQL conn; void initmysql(); int db_select(char *value); int db_delete(char *value); int db_insert(char *value); int db_update(char *value); int db_exit(); int query(char *str); void print(); #endif
stu_database.c
#include "stu_database.h" void initmysql() { mysql_init(&conn); if(!mysql_real_connect(&conn,host,username,password,database,0,NULL,0)) { printf("database failed\n"); write_logfile("%s %s %s","root","database","failed"); } } int db_select(char *value) { char sql[100]; char name[20],subject[10],num[10]; char *index; int small,large; //查询两个table的信息 if(strcmp(value,"-a")==0) { strcpy(sql,"select * from stuaddrtb"); } else if(strcmp(value,"-s")==0) { strcpy(sql,"select * from stuscoretb"); } //平均分 else if(strncmp(value,"-avr",4)==0) { if(index=strchr(value,' ')) { *index++='\0'; if(strcmp(index,"chinese")==0) { strcpy(sql,"select avg(Chinese) from stuscoretb"); } else if(strcmp(index,"maths")==0) { strcpy(sql,"select avg(Chinese) from stuscoretb"); } else if(strcmp(index,"english")==0) { strcpy(sql,"select avg(Chinese) from stuscoretb"); } else { printf("Please check the input format, detailed help\n"); } } } //查询排名 else if(strncmp(value,"-rank",5)==0) { if(index=strchr(value,' ')) { *index++='\0'; if(strcmp(index,"chinese")==0) { strcpy(sql,"select Num,Name,Chinese from stuscoretb order by Chinese desc"); } else if(strcmp(index,"maths")==0) { strcpy(sql,"select Num,Name,Maths from stuscoretb order by Maths desc"); } else if(strcmp(index,"english")==0) { strcpy(sql,"select Num,Name,English from stuscoretb order by English desc"); } else if(strcmp(index,"all")==0) { strcpy(sql,"select Num,Name,Chinese+Maths+English from stuscoretb order by Chinese+Maths+English desc"); } else { printf("Please check the input format, detailed help\n"); } } } //各科分数段的人数统计 else if(strncmp(value,"-count",6)==0) { sscanf(value,"%*s %s %d %d",&subject,&small,&large); sprintf(sql,"call p1('%s',%d,%d)",subject,small,large); } //查询某个学生的信息 else if(strncmp(value,"-s ",3)==0) { sscanf(value,"%*s %s",num); sprintf(sql,"select * from stuscoretb where Num=%s",num); } else if(strncmp(value,"-a ",3)==0) { sscanf(value,"%*s %s",num); sprintf(sql,"select * from stuaddrtb where Num=%s",num); } else { printf("Please check the input format, detailed help\n"); } query(sql); print(); } int db_delete(char *value) { char sql[1024],num[10]; sscanf(value,"%s",num); sprintf(sql,"delete stuscoretb,stuaddrtb from stuscoretb as stuscoretb left join stuaddrtb as stuaddrtb on stuscoretb.Num=stuaddrtb.Num where stuscoretb.Num=%s",num); query(sql); return 0; } int db_insert(char *value) { int c,m,e; char name[20],sql[1024]; char sex[10],birth[50],addr[50]; sscanf(value,"%s %d %d %d %s %s %s",&name,&c,&m,&e,&sex,&birth,&addr); sprintf(sql,"insert into stuscoretb(Name,Chinese,Maths,English) values('%s',%d,%d,%d)",name,c,m,e); query(sql); sprintf(sql,"insert into stuaddrtb(Name,Sex,Birth,Address) values('%s','%s','%s','%s')",name,sex,birth,addr); query(sql); return 0; } int db_update(char *value) { char *look,*val,sql[100],str[50],num[10]; sscanf(value,"%s %*s %*s",num); while(look=strchr(value,'-')) { *look='\0'; look++; if(strncmp(look,"n",1)==0) { look++; look++; sprintf(sql,"update stuscoretb set Num=%s where Num=%s",look,num); } else if(strncmp(look,"x",1)==0) { look++; look++; sprintf(sql,"update stuscoretb set Name=%s where Num=%s",look,num); } else if(strncmp(look,"c",1)==0) { look++; look++; sprintf(sql,"update stuscoretb set Chinese=%s where Num=%s",look,num); } else if(strncmp(look,"m",1)==0) { look++; look++; sprintf(sql,"update stuscoretb set Maths=%s where Num=%s",look,num); } else if(strncmp(look,"e",1)==0) { look++; look++; sprintf(sql,"update stuscoretb set English=%s where Num=%s",look,num); } else if(strncmp(look,"s",1)==0) { look++; look++; strcpy(str,look); sprintf(sql,"update stuaddrtb set Sex='%s' where Num=%s",str,num); } else if(strncmp(look,"b",1)==0) { look++; look++; strcpy(str,look); sprintf(sql,"update stuaddrtb set Birth='%s' where Num=%s",str,num); } else if(strncmp(look,"a",1)==0) { look++; look++; strcpy(str,look); sprintf(sql,"update stuaddrtb set Address='%s' where Num=%s",str,num); } else { printf("Please check the input format, detailed help\n"); } query(sql); } return 1; } int db_exit() { write_logfile("%s %s","root","exited"); mysql_close(&conn); return 0; } int query(char *str) { int m; if(n==0) { m=mysql_query(&conn,str); } else { m=mysql_next_result(&conn); m=mysql_query(&conn,str); } return 0; } void print() { int R,C,i,j; MYSQL_RES *chaxun; MYSQL_FIELD *field; MYSQL_ROW row; chaxun=mysql_store_result(&conn); if(chaxun) { C=mysql_num_fields(chaxun); R=mysql_num_rows(chaxun); for(i=0;field=mysql_fetch_field(chaxun);i++) { printf("%s\t",field->name); } printf("\n"); for(i=0;i<R;i++) { row=mysql_fetch_row(chaxun); for(j=0;j<C;j++) { printf("%s\t",row[j]); } printf("\n"); } } mysql_free_result(chaxun); n++; }
这里用的到存储过程p1
DELIMITER $$ DROP PROCEDURE IF EXISTS `p1` $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(in str varchar(20),in s int,in l int) begin if str="chinese" then select count(*) from stuscoretb where Chinese>s and Chinese<l; elseif str="maths" then select count(*) from stuscoretb where Maths>s and Maths<l; elseif str="english" then select count(*) from stuscoretb where English>s and English<l; end if; end $$ DELIMITER ;
makefile :
CC = gcc OBJS = $(wildcard *.c) TARGET = libstudatabase.so all: $(CC) $(OBJS) -fPIC -shared -o $(TARGET) mv ./$(TARGET) /lib clean: rm -rf *.o $(TARGET)
④接下来就是命令行的操作
分为 stu_readlines.h stu_readlines,c makefile
stu_readline.h
#ifndef _STU_READLINE_H #define _STU_READLINE_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<malloc.h> #include<unistd.h> #include<readline/readline.h> #include<readline/history.h> int done; int com_select PARAMS((char *)); int com_delete PARAMS((char *)); int com_insert PARAMS((char *)); int com_update PARAMS((char *)); int com_help PARAMS((char *)); int com_exit PARAMS((char *)); typedef int rl_icpfunc_t(char *); typedef struct { char *name; rl_icpfunc_t *func; char *doc; }COMMAND; char *stripwhite(char *string); int r1_help(); void initialize_readline(); char **fileman_completion PARAMS((const char *text,int start,int end)); char *command_generator(const char *text,int state); char *dupstr(char *s); int execute_line(char *line); COMMAND *find_command(char *name); #endif
stu_readlines.c
#include "stu_readline.h" COMMAND commands[] = { { "exit", com_exit, "Exit student system" }, { "help", com_help, "Display this text" }, { "update", com_update, "Update student information.\n\t\tFor:update+num -n num/-x name/-c chinese/-m maths/\n\t\t-e english/-s sex/-b birth/-a address" }, { "select", com_select, "Student information.\n\t\tFor:select -s/-a(stuaddrtb/stuscoretb)/-n+num/\n\t\t-rank chinese(maths/english)/-count chinese+score1 score2\n\t\t/-avr chinese(maths/english)" }, { "delete", com_delete, "Delete the student information.\n\t\tFor:delete+num" }, { "insert", com_insert, "Insert a student information.\n\t\tFor:insert -s+Name Chinese Maths English\n\t\tinsert -a+Sex Birth Address" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; char *stripwhite(char *string) { register char *s,*t; for(s=string;whitespace(*s);s++) { ; } if(*s==0) { return(s); } t=s+strlen(s)-1; while(t>s&&whitespace(*t)) { t--; } *++t='\0'; return s; } int execute_line(char *line) { register int i; char *word; COMMAND *command;; int len; char *name; i=0; while(line[i]&&whitespace(line[i])) { i++; } word=line+i; while(line[i]&&!whitespace(line[i])) { i++; } if(line[i]) { line[i++]='\0'; } command=find_command(word); if(!command) { printf("%s:No such command for student system\n",word); return(-1); } while(whitespace(line[i])) { i++; } word=line+i; return((*(command->func))(word)); } void initialize_readline() { rl_readline_name="STUSYSTEM-> "; rl_attempted_completion_function=fileman_completion; rl_bind_key('?', r1_help); } int r1_help() { COMMAND *command; int i,j; char *name,*word; word =rl_line_buffer; j=0; printf("?"); i = 0; while(word[i]&&whitespace(word[i])) { i++; } word = word + i; while(word[i]&&!whitespace(word[i])) { i++; } if(word[i]) { return 0; } while(name=commands[j].name) { if(strcmp(word,name)==0) { add_history(word); printf("\n\t\t%s\n",commands[j].doc); readline("STUSYSTEM-> "); return 0; } j++; } printf("\n%s: No such command for FileMan.\n",word); readline("STUSYSTEM-> "); return 0; } char **fileman_completion(const char *text,int start,int end) { char **matches; matches=(char **)NULL; if(start==0) { matches=rl_completion_matches(text,command_generator); } return(matches); } char *command_generator(const char *text,int state) { static int list_index, len; char *name; if(!state) { list_index=0; len=strlen(text); } while(name=commands[list_index].name) { list_index++; if(strncmp(name,text,len)==0) { return (dupstr(name)); } } return((char *)NULL); } char *dupstr(char *s) { char *r; r=(char *)malloc(strlen(s)+1); strcpy(r,s); return(r); } COMMAND *find_command(char *name) { register int i; for(i=0;commands[i].name;i++) { if(strcmp(name,commands[i].name)==0) { return(&commands[i]); } } return((COMMAND *)NULL); } char **data_separate(char *line) { int param_list = 0; char **parameter; char *index,*value; parameter = (char **)xmalloc((20+ 1) * sizeof (char *)); parameter[0] = (char *)NULL; while(index = strchr(line,' ')) { printf("xxxxxxxxxxxxxxxx\n"); *index = '\0'; index++; parameter[param_list] = line; printf("line:%s\n",line); line=index; printf("line:%s\nindex:%s\n",line,index); param_list+1; } parameter[param_list] = line; printf("%s %s %s",parameter[0],parameter[1],parameter[2]); return parameter; } //各个函数的实现
int com_select(char *arg) { char **param; param=data_separate(arg); printf("%s %s\n",param[0],param[1]); /*if(arg) { db_select(arg); } */ write_logfile("%s %s","root","selected"); return 0; } int com_delete(char *arg) { if(arg) { db_delete(arg); } write_logfile("%s %s","root","deleted"); return 0; } int com_insert(char *arg) { if(arg) { db_insert(arg); } write_logfile("%s %s","root","inserted"); return 0; } int com_update(char *arg) { if(arg) { db_update(arg); } write_logfile("%s %s","root","updated"); return 0; } int com_exit(char *arg) { db_exit(); done=1; return 0; } int com_help(char *arg) { register int i; int printed=0; for(i=0;commands[i].name;i++) { if(!*arg||(strcmp(arg,commands[i].name)==0)) { printf ("%s\t\t%s.\n",commands[i].name,commands[i].doc); printed++; } } if (!printed) { printf("No commands match `%s'. Possibilties are:\n",arg); for(i=0;commands[i].name;i++) { if(printed==6) { printed = 0; printf ("\n"); } printf("%s\t",commands[i].name); printed++; } if(printed) { printf ("\n"); } } write_logfile("%s %s","root","helped"); return 0; }
makefile
CC = gcc OBJS = $(wildcard *.c) TARGET = libstureadlines.so all: $(CC) $(OBJS) -fPIC -shared -o $(TARGET) mv ./$(TARGET) /lib clean: rm -rf *.o $(TARGET)
⑤最后是主函数了,可放在stuinfo下面即可
分为 stu_mian.h stu_main.c makefile
stu_mian.h
#ifndef _STU_MAIN_H #define _STU_MAIN_H #include<stdio.h> #include<stdlib.h> #include "./readlines/stu_readline.h" #include<readline/readline.h> #include<readline/history.h> void landing(); void welcome(); #endif
stu_main.c
#include "stu_main.h" void landing() { int n; char user[10],*pwd; printf("login as: "); scanf("%s",&user); user[strlen(user)]='\0'; pwd=getpass("password: "); n=judgepasswd(user,pwd); if(n) { welcome(); initmysql(); write_logfile("%s %s","root","login in"); } else { done=1; } } void welcome() { printf("**********************************************************\n"); printf("* welcome to student system! *\n"); printf("* input help to understand how to operate student system *\n"); printf("* command + ? to show help *\n"); printf("**********************************************************\n"); } int main(int argc,char **argv) { char *line,*s; done=0; landing(); initialize_readline(); for(;done==0;) { line=readline("STUSYSTEM-> "); if(!line) break; s=stripwhite(line); if(*s) { add_history(s); execute_line(s); } free(line); } exit(0); return 0; }
makefile
CC = gcc TARGET = stuinfo OBJS = $(wildcard *.c) MYLAB = -L/lib -lstudatabase -L/lib -lstureadconf -L/lib -lstuwritelog -L/lib -lstureadlines all: cd ./database;make cd ./readconfig;make cd ./writelogfile;make cd ./readlines;make $(CC) -o $(TARGET) $(OBJS) $(MYLAB) -lmysqlclient -lncurses -lreadline clean: rm -rf *.o $(TARGET) cd ./database;make clean cd ./readconfig;make clean cd ./writelogfile;make clean cd ./readlines;make clean
运行效果: