学生信息管理系统SIMS

用java开发学生信息管理系统(SIMS,三) 现在来看看选项菜单下的新增用户这个功能。如下图         这个新增用户是指由管理员登陆SIMS后创建新用户(普通用户),并设置此用户的权限许可,只有管理员才能创建用户和设置权限许可(或在高级功能中修改权限许可)。如果在未登录或以普通用户身份登陆的情况下点击“新增用户”,SIMS会弹出不允许操作的提示消息,如下图         管理员登陆和普通用户登陆使用的是同一个登录界 阅读详情
学生信息管理系统SIMS

[root@matrix sims]# ll
总计 108
-rwxr-xr-x 1 root root 23947 05-08 23:50 a
-rw-r--r-- 1 root root   198 05-04 12:00 ABOUT
-rw-r--r-- 1 root root    43 05-07 16:44 demo.c
-rw-r--r-- 1 root root   288 05-05 13:58 EXAMPLE
-rw-r--r-- 1 root root   401 05-08 23:50 main.c
-rw-r--r-- 1 root root   291 05-04 20:22 Makefile
-rw-r--r-- 1 root root 17960 05-07 20:17 misc.c
-rw-r--r-- 1 root root  3088 05-07 20:17 misc.h
-rw-r--r-- 1 root root   140 05-04 12:03 README
[root@matrix sims]# make
gcc -c main.c
gcc -c misc.c
gcc -o a main.o misc.o
[root@matrix sims]# a

////////欢迎使用(学生信息管理系统SIMS)\\\\\\\\
______________________________________________
用户名: root
口令: hacker
认证失败,请检查字母大小写是否正确。
用户名: root
口令: hacking
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 0
[X]记录查询失败!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 1
______________________________________________
当前位置(主页/添加记录)
学号: 101
姓名: Jeff Conrad
性别: M
年龄: 24
电话: 10086
出生(年): 1988
出生(月): 3
出生(日): 24
语文成绩: 78
数学成绩: 78
英语成绩: 88
本次索引节点为1
[V]记录添加成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 1
______________________________________________
当前位置(主页/添加记录)
学号: 102
姓名: Junkie Pro
性别: F
年龄: 25
电话: 10000
出生(年): 1988
出生(月): 4
出生(日): 3
语文成绩: 99
数学成绩: 34
英语成绩: 55
本次索引节点为2
[V]记录添加成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 1
______________________________________________
当前位置(主页/添加记录)
学号: 101
[X]ID冲突!
学号: 103
姓名: Lady GaGa
性别: M
年龄: 35
电话: 12580
出生(年): 1978
出生(月): 8
出生(日): 3
语文成绩: 99
数学成绩: 56
英语成绩: 44
本次索引节点为3
[V]记录添加成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 0
学号 姓名         性别 年龄 电话        出生       语文 数学 英语 节点
......................................................................
101  Jeff Conrad  M    24   10086       1988-03-24 78   78   88   1  
102  Junkie Pro   F    25   10000       1988-04-03 99   34   55   2  
103  Lady GaGa    M    35   12580       1978-08-03 99   56   44   3  
......................................................................
记录: 共3项
[V]记录查询成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 1
关键字: a
学号 姓名         性别 年龄 电话        出生       语文 数学 英语 节点
......................................................................
101  Jeff Conrad  M    24   10086       1988-03-24 78   78   88   1  
103  Lady GaGa    M    35   12580       1978-08-03 99   56   44   3  
......................................................................
记录: 共2项
[V]记录查询成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 2
资料: 学号( 0) 姓名( 1) 性别( 2) 年龄( 3) 电话( 4) 
生日: 年份( 5) 月份( 6) 号数( 7) 
成绩: 语文( 8) 数学( 9) 英语(10)
序号: 2
性别: M
101  Jeff Conrad  M    24   10086       1988-03-24 78   78   88   1  
103  Lady GaGa    M    35   12580       1978-08-03 99   56   44   3  
......................................................................
记录: 共2项
[V]记录查询成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 2
______________________________________________
学号: 104
[X]ID无效!
学号: 103
确定删除? (y or n): y
[V]记录删除成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 0
学号 姓名         性别 年龄 电话        出生       语文 数学 英语 节点
......................................................................
101  Jeff Conrad  M    24   10086       1988-03-24 78   78   88   1  
102  Junkie Pro   F    25   10000       1988-04-03 99   34   55   2  
......................................................................
记录: 共2项
[V]记录查询成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 3
______________________________________________
学号: 101
姓名: Jeff Conrad
性别: F
年龄: 10086
电话: 10086
出生(年): 1989
出生(月): 3
出生(日): 26
语文成绩: 99
数学成绩: 98
英语成绩: 98
[V]记录修改成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 4
______________________________________________
全部(0) 模糊(1) 条件(2)
查询方式: 0
学号 姓名         性别 年龄 电话        出生       语文 数学 英语 节点
......................................................................
101  Jeff Conrad  F    1008610086       1989-03-26 99   98   98   1  
102  Junkie Pro   F    25   10000       1988-04-03 99   34   55   2  
......................................................................
记录: 共2项
[V]记录查询成功!
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 6
______________________________________________
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
功能模块:
        增加  删除  修改  查询
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
按下回车键返回: 
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 7
______________________________________________
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                欢迎使用SIMS v3
版本: 3.0.0
发行者: Junkie Pro
创建日期: 2013年05月01日
QQ: 614616185
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
按下回车键返回: 
______________________________________________
增加(1) 删除(2) 修改(3) 查询(4)
设置(5) 帮助(6) 关于(7) 退出(0)
选项: 0
______________________________________________
______________________________________________
\\\\\\\\感谢使用(学生信息管理系统SIMS)////////
[root@matrix sims]# 




[root@matrix sims]# '/root/project/sims/ABOUT' 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		欢迎使用SIMS v3
版本: 3.0.0
发行者: Junkie Pro
创建日期: 2013年05月01日
QQ: 614616185
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


[root@matrix sims]# '/root/project/sims/README' 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
功能模块:
	增加  删除  修改  查询
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



[root@matrix sims]# '/root/project/sims/Makefile' 
a: misc.h main.o misc.o
	gcc -o a main.o misc.o
misc.o: misc.h misc.c
	gcc -c misc.c
main.o: misc.h main.c
	gcc -c main.c
clean:
	rm -f *.o
reset: 
	rm -f DATABASE.DB
restore: 
	ls -l EXAMPLE && cp -f EXAMPLE DATABASE.DB && echo RESTORE OK || echo NO EXAMPLE
help:
	clear
	cat README | more


[root@matrix sims]# '/root/project/sims/DATABASE.DB' 



[root@matrix sims]# '/root/project/sims/EXAMPLE' 


[root@matrix sims]# '/root/project/sims/main.c' 
#include "misc.h"
int main(){
	system("clear");
	Head();
	if (Login("root", "hacking", 3)){//待办----文件
		Tail();
		return -1;
	}
	while (1){
		DividingLine('_', 1, 46);
		Body();
		int cn = ChoiceNumber("", OPTION_EXIT, OPTION_ABOUT, 3);
		if (-1 == cn){
			Tail();
			return -1;//建议不在此使用break;以增强程序的扩展性
		}
		if (Execute(cn))
			break;
	}
	Tail();
	return 0;
}


[root@matrix sims]# '/root/project/sims/misc.h' 
#ifndef __MISC_H__
#define __MISC_H__
#define DATABASE "DATABASE.DB"
#define TABLE_HEAD 128
#define TABLE_TAIL 256
#define KEYWORD_LIMIT 100//关键字上限为100个字符(百度一下,你就知道)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//enum枚举: 默认从0开始递增, 手动起始值(保险起见)
enum {DATATYPE_CHAR = 0, DATATYPE_INT, DATATYPE_FLOAT, DATATYPE_DOUBLE, DATATYPE_STRING};
enum {OPTION_EXIT = 0, OPTION_ADD, OPTION_DEL, OPTION_EDIT, OPTION_QUERY, OPTION_SETTING, OPTION_HELP, OPTION_ABOUT};
typedef enum {QUERY_ALL, QUERY_LIKE, QUERY_WHERE} query_e;//将QUERY_ALL排在第一位是因为键盘布局
typedef enum {CON_ID = 0, CON_NAME, CON_SEX, CON_AGE, CON_TELEPHONE, CON_YEAR, CON_MONTH, CON_DAY, CON_CHINESE, CON_MATH, CON_ENGLISH, } CONDITION;//看个人习惯,建议设置为0,而不是1
enum {SYMBOL_YES, SYMBOL_NO};//数字数位
typedef struct {size_t year, month, day;} date_s;
typedef struct {
	char fill_a:3;
	size_t content;
	char fill_b:5;
} table_s;
typedef struct {
	table_s start;
	size_t id;
	char name[20];
	char sex[4];
	size_t age;
	char telephone[12];
	date_s birth;
	struct result_s {
		size_t chinese, math, english;
	} score;
	size_t inode;
	table_s end;
} student_s;
int Login(const char *username, const char *password, size_t n);//登录
void CleanStdin(void);//清理stdin流中残留数据
int ClearLF(char *str, size_t n);//清除字符串中'\n'字符 LF(line feed)
int IsNull(const char *str);//检测字符串是否为空
void Head(void);//显示系统头部信息
void Body(void);//显示系统主要信息
void Tail(void);//显示系统退出信息
int ChoiceNumber(const char *prompt, int begin, int end, size_t n);//选择数字
int IsExistID(size_t s_id);//检测ID是否存在
int Edit(size_t n);//修改记录
int Del(size_t n);//删除记录
int Execute(size_t n);//执行对应功能
int IsExistFile(const char *path);//检测文件是否存在
int ReadText(const char *path);//显示文本文件内容
void DividingLine(int c, size_t row, size_t col);//打印分界线
int Add(const size_t etc);//添加记录
int GetData(const char *prompt, int type, void *var, size_t n);//输入数据
int GetString(const char *prompt, char *ptr, size_t len, size_t n);//输入字符串
int ProduceInode(void);//生成索引节点
int CountRecord(void);//统计记录条目
int SearchString(const char *keyword, const char *content);//搜索字符串
void InitCA(char *ca, size_t n);//初始化字符数组
int Query(int flag);//查询所有数据
void ShowMe(const char *path, const char *object);//显示指定文本内容
int ChooseKey(const char *prompt);//获取一个按键
int NumericDigits(int integer, int flag);
int DigitalConversionString(int integer, char *buf, size_t size, int flag);
int ReverseString(char *src, size_t len);//逆转字符串
void Debug(void);
#endif//__MISC_H__
//增加重建索引节点,序列递增修改原始节点号,
//1,3,5//在生成新节点后删除了2号节点
//1,2,3//重建索引节点后
//可以按照索引节点进行数据库排序



[root@matrix sims]# '/root/project/sims/misc.c' 
#include "misc.h"
int Login(const char *username, const char *password, size_t n){;
	if (!(username && password))
		return -1;
	size_t len_user = strlen(username), 
		   len_pswd = strlen(password);
	if (!(len_user && len_pswd))
		return -1;
	char rec_user[len_user + 2], 
		 rec_pswd[len_pswd + 2];//多一个字节用于检测用户是否过多输入
	size_t siz_user = sizeof(rec_user), 
		   siz_pswd = sizeof(rec_pswd);
	while(n--){
		printf("用户名: ");
		fgets(rec_user, siz_user, stdin);
		if (IsNull(rec_user))
			if (ClearLF(rec_user, strlen(rec_user)))
				CleanStdin();
		printf("口令: ");
		fgets(rec_pswd, siz_pswd, stdin);
		if (IsNull(rec_pswd))
			if (ClearLF(rec_pswd, strlen(rec_pswd)))
				CleanStdin();
		if (strcmp(username, rec_user) || strcmp(password, rec_pswd)){
			puts("认证失败,请检查字母大小写是否正确。");
			continue;
		}
		return 0;
	}
	return -1;
}
void CleanStdin(void){
	scanf("%*[^\n]");
	scanf("%*c");
}
int ClearLF(char *str, size_t n){
	int i = 0;
	for (i = 0; i < n; i++)
		if ('\n' == str[i]){
			str[i] = '\0';
			return 0;
		}
	return -1;
}
int IsNull(const char *str){;
	if (!str)
		return 0;
	return strlen(str) > 0 ? -1 : 0;
}
void Head(void){
	puts("////////欢迎使用(学生信息管理系统SIMS)\\\\\\\\\\\\\\\\");
	DividingLine('_', 1, 46);
}
void Body(void){
	printf("增加(%d)\t删除(%d)\t修改(%d)\t查询(%d)\n设置(%d)\t帮助(%d)\t关于(%d)\t退出(%d)\n", 
			OPTION_ADD, OPTION_DEL, OPTION_EDIT, OPTION_QUERY, OPTION_SETTING, OPTION_HELP, OPTION_ABOUT, OPTION_EXIT);
}
void Tail(void){
	DividingLine('_', 1, 46);
	puts("\\\\\\\\\\\\\\\\感谢使用(学生信息管理系统SIMS)////////");
}
int ChoiceNumber(const char *prompt, int begin, int end, size_t n){
	while(n--){
		int num = -1;
		printf("%s: ", IsNull(prompt) ? prompt : "选项");
		int sv = scanf("%d", &num);
		CleanStdin();
		if (sv && num >= begin && num <= end)
			return num;
		printf("[X]错误%s!\n", IsNull(prompt) ? prompt : "选项");
	}
	return -1;
}
int IsExistID(size_t s_id){
	int res = -1;
	if (IsExistFile(DATABASE))
		return -1;
	FILE *fp = fopen(DATABASE, "rb");
	if (!fp)
		return -1;
	student_s t = {};
	while(!feof(fp)){
		if (1 != fread(&t, sizeof(student_s), 1, fp))
			break;
		if (s_id == t.id){
			res = 0;
			break;
		}
	}
	fclose(fp);
	fp = NULL;
	return res;
}
int Edit(size_t n){;
	if (IsExistFile(DATABASE))
		return -1;
	int dest = -1;
	int sid = -1;
	while(n--){
		if (!GetData("学号", DATATYPE_INT, &sid, 1))
			if (!IsExistID(sid)){
				dest = 0;
				break;
			}
			else 
				puts("[X]ID无效!");
	}
	if (dest)
		return -1;
	FILE *fp = fopen(DATABASE, "rb+");
	if (!fp)
		return -1;
	student_s tmp = {};
	int res = !0;
	while (!feof(fp)){
		if (1 != fread(&tmp, sizeof(student_s), 1, fp))
			break;
		if (sid == tmp.id){
			res = res && 
				!GetString("姓名", tmp.name, sizeof(tmp.name) / sizeof(*tmp.name), 2) && 
				!GetString("性别", tmp.sex, sizeof(tmp.sex) / sizeof(*tmp.sex), 2) && 
				!GetData("年龄", DATATYPE_INT, &tmp.age, 2) && 
				!GetString("电话", tmp.telephone, sizeof(tmp.telephone) / sizeof(*tmp.telephone), 2) && 
				!GetData("出生(年)", DATATYPE_INT, &tmp.birth.year, 2) && 
				!GetData("出生(月)", DATATYPE_INT, &tmp.birth.month, 2) && 
				!GetData("出生(日)", DATATYPE_INT, &tmp.birth.day, 2) && 
				!GetData("语文成绩", DATATYPE_INT, &tmp.score.chinese, 2) && 
				!GetData("数学成绩", DATATYPE_INT, &tmp.score.math, 2) && 
				!GetData("英语成绩", DATATYPE_INT, &tmp.score.english, 2);
			if (res){
				fseek(fp, -sizeof(student_s), SEEK_CUR);
				if (1 == fwrite(&tmp, sizeof(tmp), 1, fp)){
					fclose(fp);
					fp = NULL;
					return 0;
				}
			}
			fclose(fp);
			fp = NULL;
			return -1;
		}
	}
}
int Del(size_t n){
	size_t sid = 0;
	if (IsExistFile(DATABASE))
		return -1;
	while (n--){
		if (!GetData("学号", DATATYPE_INT, &sid, 1)){
			if (IsExistID(sid))
				puts("[X]ID无效!");
			else
				break;
		}
	}
	if (-1 == n)
		return -1;
	n = 3;
	int cn = 0;
	while(n--){
		cn = ChooseKey("确定删除? (y or n)");
		if ('n' == cn)
			return -1;
		else if ('y' == cn)
			break;
	}
	if (-1 == n)
		return -1;
	FILE *fp = fopen(DATABASE, "rb");
	if (!fp){
		fclose(fp);
		fp = NULL;
		return -1;
	}
	int con = 1;
	while (con){
		char *tfa = "tmp_";
		int tfb = rand();
		char tf[strlen(tfa) + NumericDigits(tfb, SYMBOL_NO) + 1];
		InitCA(tf, sizeof(tf));
		sprintf(tf, "%s%d", tfa, tfb);
		tf[sizeof(tf) - 1] = 0;
		if (IsExistFile(tf)){
			con = 0;
			FILE *dest = fopen(tf, "wb+");
			if (!dest)
				return -1;
			FILE *src = fopen(DATABASE, "rb");
			if (!src){
				fclose(dest);
				dest = NULL;
				return -1;
			}
			student_s ts = {};
			while(!feof(src)){
				if (1 != fread(&ts, sizeof(student_s), 1, src))
					break;
				if (sid != ts.id)
					if (1 != fwrite(&ts, sizeof(student_s), 1, dest))
						break;
			}
			fclose(dest);
			fclose(src);
			dest = src = NULL;
			remove(DATABASE);
			rename(tf, DATABASE);
			return 0;
		}
	}
	return -1;
}

int Execute(size_t n){
	DividingLine('_', 1, 46);
	switch(n){
		case OPTION_EXIT:
			return -1;
		case OPTION_ADD:
			if (Add(3))
				puts("[X]记录添加失败!");
			else
				puts("[V]记录添加成功!");
			break;
		case OPTION_DEL:
			if (Del(3))
				puts("[X]记录删除失败!");
			else
				puts("[V]记录删除成功!");
			break;
		case OPTION_EDIT:
			if (Edit(3))
				puts("[X]记录修改失败!");
			else
				puts("[V]记录修改成功!");
			break;
		case OPTION_QUERY:
			printf("全部(%d) 模糊(%d) 条件(%d)\n", QUERY_ALL, QUERY_LIKE, QUERY_WHERE);
			query_e flag = QUERY_ALL;
			flag = ChoiceNumber("查询方式", QUERY_ALL, QUERY_WHERE, 3);
			if (CountRecord() <= 0 || Query(flag))//目前可以省略CountRecord();该形式表达式可以在其它功能中采用
				puts("[X]记录查询失败!");
			else
				puts("[V]记录查询成功!");
			break;
		case OPTION_SETTING:
			puts("初始化数据库?");
			break;
		case OPTION_HELP:
			ShowMe("README", "帮助文档");
			break;
		case OPTION_ABOUT:
			ShowMe("ABOUT", "关于文档");
			break;
		default:;
	}
	return 0;//为了扩展性暂时不写在default范围内
}
int IsExistFile(const char *path){;
	if (!IsNull(path))
		return -1;
	FILE *fp = fopen(path, "r");
	if (fp){
		fclose(fp);
		fp = NULL;
		return 0;
	}
	return -1;
}
int ReadText(const char *path){
	FILE *fp = fopen(path, "rt");
	int c = -1;
	if (fp){
		while((c = fgetc(fp)) != EOF)
			putc(c, stdout);
		fclose(fp);
		fp = NULL;
	}
	else
		return -1;
	return 0;
}
void DividingLine(int c, size_t row, size_t col){
	int i = 0;
	while (row--){
		for (i = 0; i < col; i++)
			printf("%c", c);
		puts("");
	}
}
int Add(const size_t etc){
	puts("当前位置(主页/添加记录)");//可以使用函数来改写
	FILE *fp = NULL;
	if (IsExistFile(DATABASE)){
		fp = fopen(DATABASE, "wb+");
		if (!fp)
			return -1;
	}
	else {
		fp = fopen(DATABASE, "ab+");//追加总是在末尾写入,rb+覆盖写入,不允许追加,在原有基础上修改
		if (!fp)
			return -1;
	}
	int n = etc;
	//使用结构体指针,巩固知识点。
	student_s dat = {0};
	dat.start.content = TABLE_HEAD;
	dat.end.content = TABLE_TAIL;
	int res = 0;
	int tms = 2;
	while(tms--){
		if (!GetData("学号", DATATYPE_INT, &dat.id, 1))
			if (IsExistID(dat.id)){
				res = !0;
				break;
			}
			else
				puts("[X]ID冲突!");
	}
	res = res && 
		!GetString("姓名", dat.name, sizeof(dat.name) / sizeof(*dat.name), 2) && 
		!GetString("性别", dat.sex, sizeof(dat.sex) / sizeof(*dat.sex), 2) && 
		!GetData("年龄", DATATYPE_INT, &dat.age, 2) && 
		!GetString("电话", dat.telephone, sizeof(dat.telephone) / sizeof(*dat.telephone), 2) && 
		!GetData("出生(年)", DATATYPE_INT, &dat.birth.year, 2) && 
		!GetData("出生(月)", DATATYPE_INT, &dat.birth.month, 2) && 
		!GetData("出生(日)", DATATYPE_INT, &dat.birth.day, 2) && 
		!GetData("语文成绩", DATATYPE_INT, &dat.score.chinese, 2) && 
		!GetData("数学成绩", DATATYPE_INT, &dat.score.math, 2) && 
		!GetData("英语成绩", DATATYPE_INT, &dat.score.english, 2) && 
		!(-1 == (dat.inode = ProduceInode()));//在即将写入文件时删除数据文件返回失败状态(-1)
	if (res){
		if (1 != fwrite(&dat, sizeof(student_s), 1, fp)){
			puts("[X]写入数据时发生错误!");
			fclose(fp);
			fp = NULL;//FILE*关闭后仍可用,虽不能真正写入文件,但程序可能照常运行,置为空指针,则写入是会段错误,便于发现潜在隐患
			return -1; 
		}
		printf("本次索引节点为%d\n", dat.inode);
		fclose(fp);
		fp = NULL;
		return 0;
	}
	fclose(fp);
	fp = NULL;
	return -1;
}
int GetData(const char *prompt, int type, void *var, size_t n){
	while (n--){
		printf("%s: ", prompt);
		int is = 0;
		switch (type){
			case DATATYPE_CHAR:
				is = scanf("%c", var);
				break;
			case DATATYPE_INT:
				is = scanf("%d", var);
				break;
			case DATATYPE_FLOAT:
			case DATATYPE_DOUBLE:
				is = scanf("%f", var);
				break;
			case DATATYPE_STRING:
				//is = fgets/scanf("%s")
				break;
			default:
				return -1;
		}
		CleanStdin();
		if (is)
			return 0;
		puts("[X]输入错误!");
	}
	return -1;
}
int GetString(const char *prompt, char *ptr, size_t len, size_t n){
	while(n--){
		printf("%s: ", prompt);
		fgets(ptr, len, stdin);
		if (IsNull(ptr)){
			if (ClearLF(ptr, strlen(ptr)))
				CleanStdin();
			if (IsNull(ptr))
				return 0;
		}
	}
	return -1;
}
int ProduceInode(void){;
	size_t inode = 0;
	if (IsExistFile(DATABASE))
		return -1;
	FILE *fp = fopen(DATABASE, "rb");
	if (!fp)
		return -1;
	student_s t = {};
	while(!feof(fp))
		if (1 == fread(&t, sizeof(student_s), 1, fp))
			inode = t.inode > inode ? t.inode : inode;
	fclose(fp);
	fp = NULL;
	return ++inode;
}
int CountRecord(void){;
	size_t count = 0;
	if (IsExistFile(DATABASE))
		return -1;
	FILE *fp = fopen(DATABASE, "rb");
	if (!fp)
		return -1;
	student_s t;
	while(!feof(fp))
		if (1 == fread(&t, sizeof(student_s), 1, fp)){
			if (t.start.content != TABLE_HEAD || t.end.content != TABLE_TAIL)//主要检测表头
				return -1;
			count++;
		}
	if (ftell(fp) != count * sizeof(student_s))//检测表尾
		return -1;
	fclose(fp);
	fp = NULL;
	return count;
}
int SearchString(const char *keyword, const char *content){;
	if (!(IsNull(keyword) && IsNull(content)))
		return -1;
	size_t len_k = strlen(keyword), 
		   len_c = strlen(content);
	if (len_k > len_c)
		return -1;
	int i = 0, j = 0;
	char match[len_k + 1];
	for (i = 0; i < len_c - len_k + 1; i++){//关系类型: 一对多
		InitCA(match, sizeof(match));
		for (j = i; j < i + len_k; j++)
			match[j - i] = content[j];
		match[j - i] = 0;
		if (!strcmp(match, keyword))
			return 0;
	}
	return -1;
}
void InitCA(char *ca, size_t n){
	int i = 0;
	for (i = 0; i < n; i++)
		ca[i] = 0;
}
//usleep(500000);//睡眠0.1秒钟
//检测字段是否为ASCII字符集中数据,否则认为是汉子,占用不同的位宽//编写整数转换字符串函数sprintf
int Query(int flag){;
	if (CountRecord() <= 0)
		return -1;
	FILE *fp = fopen(DATABASE, "rb");
	if (!fp)
		return -1;
	student_s t = {};
	size_t cnt = 0;
	void Header(void){
		puts("学号 姓名         性别 年龄 电话        出生       语文 数学 英语 节点");
		DividingLine('.', 1, 70);
	}
	void Footer(const char *NullPrompt){
		DividingLine('.', 1, 70);
		if (!cnt)
			if (IsNull(NullPrompt))
				puts(NullPrompt);
			else
				puts("[*]数据库文件已发生变化!");
		printf("记录: 共%u项\n", cnt);
	}
	void format(char *buf){//根据非ASCII字符个数和ASCII个数来确定%s,其它数据类型保持不变

	}
	int SAll(void){
		Header();
		while (!feof(fp)) {
			if (1 != fread(&t, sizeof(student_s), 1, fp))
				break;
			printf("%-5u%-13s%-5s%-5u%-12s%04u-%02u-%02u %-5u%-5u%-5u%-3u\n", t.id, t.name, t.sex, t.age, t.telephone, t.birth.year, t.birth.month, t.birth.day, t.score.chinese, t.score.math, t.score.english, t.inode), cnt++;
		}
		fclose(fp);
		fp = NULL;
		Footer(NULL);
		return 0;
	}
	int SLike(const char *keyword){
		Header();
		char buf[KEYWORD_LIMIT + 1] = {0};
		while (!feof(fp)) {
			if (1 != fread(&t, sizeof(student_s), 1, fp))
				break;
			int c = -1;
#define MATCHING(Flag, Var) \
			InitCA(buf, sizeof(buf)); \
			sprintf(buf, #Flag, Var); \
			/*printf("正在匹配第%d项中的%s\n", ftell(fp) / sizeof(student_s), #Var);*/ \
			c = c && SearchString(keyword, buf); \
			if (!c) break;//该行语句属于宏MATCHING
			int wc = 1;
			while (wc--){
				MATCHING(%u,  t.id);
				MATCHING(%s,  t.name);
				MATCHING(%s,  t.sex);
				MATCHING(%u,  t.age);
				MATCHING(%s,  t.telephone);
				MATCHING(%u,  t.birth.year);
				MATCHING(%u,  t.birth.month);
				MATCHING(%u,  t.birth.day);
				MATCHING(%u,  t.score.chinese);
				MATCHING(%u,  t.score.math);
				MATCHING(%u,  t.score.english);
			}
			if (!c)
				printf("%-5u%-13s%-5s%-5u%-12s%04u-%02u-%02u %-5u%-5u%-5u%-3u\n", t.id, t.name, t.sex, t.age, t.telephone, t.birth.year, t.birth.month, t.birth.day, t.score.chinese, t.score.math, t.score.english, t.inode), cnt++;
		}
		fclose(fp);
		fp = NULL;
		Footer("[*]没有匹配内容!");
		return 0;
	}
	int SWhere(void){
#define PREC printf("%-5u%-13s%-5s%-5u%-12s%04u-%02u-%02u %-5u%-5u%-5u%-3u\n", src.id, src.name, src.sex, src.age, src.telephone, src.birth.year, src.birth.month, src.birth.day, src.score.chinese, src.score.math, src.score.english, src.inode), cnt++;
		printf("资料: 学号(%2d) 姓名(%2d) 性别(%2d) 年龄(%2d) 电话(%2d) \n生日: 年份(%2d) 月份(%2d) 号数(%2d) \n成绩: 语文(%2d) 数学(%2d) 英语(%2d)\n", 
				CON_ID, CON_NAME, CON_SEX, CON_AGE, CON_TELEPHONE, CON_YEAR, CON_MONTH, CON_DAY, CON_CHINESE, CON_MATH, CON_ENGLISH);
		int cn = ChoiceNumber("序号", CON_ID, CON_ENGLISH, 3);
		if (-1 == cn)
			return -1;
		student_s dest = {0}, src = {0};
		int res = -1;
#define DECIDE(C) \
		if (-1 == (C)) {\
			fclose(fp); \
			fp = NULL; \
			return -1; \
		}
#define DPI(arg1, arg2) \
		while (!feof(fp)) {\
			if (1 != fread(&src, sizeof(student_s), 1, fp)) break;\
			if (arg1 == arg2) PREC;}
#define DPS(arg1, arg2) \
		while (!feof(fp)) {\
			if (1 != fread(&src, sizeof(student_s), 1, fp)) break;\
			if (!strcmp(arg1, arg2)) PREC;}
		switch (cn) {
			case CON_ID:
				DECIDE(GetData("学号", DATATYPE_INT, &dest.id, 2));
				DPI(dest.id, src.id);
				break;
			case CON_NAME:
				DECIDE(GetString("姓名", dest.name, sizeof(dest.name) / sizeof(*dest.name), 2));
				DPS(dest.name, src.name);
				break;
			case CON_SEX:
				DECIDE(GetString("性别", dest.sex, sizeof(dest.sex) / sizeof(*dest.sex), 2));
				DPS(dest.sex, src.sex);
				break;
			case CON_AGE:
				DECIDE(GetData("年龄", DATATYPE_INT, &dest.age, 2));
				DPI(dest.age, src.age);
				break;
			case CON_TELEPHONE:
				DECIDE(GetString("电话", dest.telephone, sizeof(dest.telephone) / sizeof(*dest.telephone), 2));
				DPS(dest.telephone, src.telephone);
				break;
			case CON_YEAR:
				DECIDE(GetData("年份", DATATYPE_INT, &dest.birth.year, 2));
				DPI(dest.birth.year, src.birth.year);
				break;
			case CON_MONTH:
				DECIDE(GetData("月份", DATATYPE_INT, &dest.birth.month, 2));
				DPI(dest.birth.month, src.birth.month);
				break;
			case CON_DAY:
				DECIDE(GetData("号数", DATATYPE_INT, &dest.birth.day, 2));
				DPI(dest.birth.day, src.birth.day);
				break;
			case CON_CHINESE:
				DECIDE(GetData("语文", DATATYPE_INT, &dest.score.chinese, 2));
				DPI(dest.score.chinese, src.score.chinese);
				break;
			case CON_MATH:
				DECIDE(GetData("数学", DATATYPE_INT, &dest.score.math, 2));
				DPI(dest.score.math, src.score.math);
				break;
			case CON_ENGLISH:
				DECIDE(GetData("英语", DATATYPE_INT, &dest.score.english, 2));
				DPI(dest.score.english, src.score.english);
				break;
		}
		fclose(fp);
		fp = NULL;
		Footer("[*]没有匹配内容!");
		return 0;
	}
	if (QUERY_ALL == flag){
		return SAll();
	}
	else if (QUERY_LIKE == flag){
		char keyword[KEYWORD_LIMIT + 1];
		InitCA(keyword, sizeof(keyword));
		if (GetString("关键字", keyword, sizeof(keyword), 3)){
			fclose(fp);
			fp = NULL;
			return -1;
		}
		return SLike(keyword);
	}
	else if (QUERY_WHERE == flag){
		return SWhere();
	}
	else
		return -1;
}
void ShowMe(const char *path, const char *object){
	if (IsExistFile(path)){
		printf("[X]打开%s失败!\n", object);
		return ;
	}
	ReadText(path);
	ChooseKey(NULL);
}
int ChooseKey(const char *prompt){
	int c = 0;
	if (!IsNull(prompt))
		prompt = "按下回车键返回";
	printf("%s: ", prompt);
	if ('\n' != (c = fgetc(stdin)))
		CleanStdin();
	return c;	
}
int NumericDigits(int integer, int flag){//条件查询可能不用这个函数,条件查询中直接比较两个值是否完全相等,包含数据类型
	int count = 0;
	if (SYMBOL_YES == flag)//仅限于符号
		count = integer < 0 ? 1 : 0;
	else if (SYMBOL_NO == flag);
	else
		return -1;
	integer = integer < 0 ? -1 * integer : integer;
	do {
		count++;
		integer /= 10;
	} while (integer);
	return count;
}
int DigitalConversionString(int integer, char *buf, size_t size, int flag){//字符串转换数字,使用逆向算法即可int-'0'
	InitCA(buf, size);
	if (SYMBOL_YES == flag){
		if (integer < 0)
			*buf++ = '-';
	}
	else if (SYMBOL_NO == flag);
	else
		return -1;
	integer = integer < 0 ? -1 * integer : integer;//可以省略该条语句,直接对负数操作效果一样
	do {
		*buf++ = '0' + integer % 10;
		integer /= 10;
	} while (integer);
	return 0;
}
int ReverseString(char *src, size_t len){//将来为了支持WHERE *str*;
	char buf[len + 1];
	InitCA(buf, sizeof(buf));
	strcpy(buf, src);
	int i = 0;
	for (i = 0; i < len; i++){
		src[i] = buf[len - i - 1];
	}
	puts(buf);
	puts(src);
}
void Debug(void){
	int i = -54321;
	int is = NumericDigits(i, SYMBOL_YES);
	char buf[is + 1];
	printf("-----%d\n", sizeof(buf));
	DigitalConversionString(i, buf, is, SYMBOL_YES);
	DigitalConversionString(i, buf, is, SYMBOL_YES);
	puts(buf);
	ReverseString(buf, strlen(buf));
}



学生信息管理系统(SIMS) 关于学校里的那点事情,自己没事情开发的(开发文挡全) 立即下载

相关推荐

sims学生信息管理系统

学生信息管理外文翻译 撒旦撒上大三大四的

学生信息管理系统(student information manage system, SIMS)

本项目为学生信息管理系统,使用C语言编写,代码附有详细注释。提供功能包括:学生信息的查询、修改、增加、删除;账户信息的查询、修改、增加、删除。

仅以此博客记录日常学习工作中所思所得,水平有限,难登大雅,万望海涵。 1290

学生信息管理系统 SIMS

数据库是SQL Server 2008的数据库,MVC+Servlet+JavaBean开发的学生信息管理系统,界面清晰,功能齐全,可以运行。

SIMS 学习信息管理系统使用教程

SIMS 学习信息管理系统使用教程 1. 项目介绍 SIMS(Student Information Management System)是一个基于 Java Swing 和 I/O 技术开发的学习信息管理系统。该系统主要用于管理学生的学习信息,包括成绩查询、学生信息管理、登录日志记录等功能。系统支持管理员和普通学生两种用户角色,管理员可以进行学生信息的增删查改操作,而学生只能查询自己的成绩和修改...

gitblog_00664的博客 545

迈德威视相机调用( 基于 Linux系统+ OpenCV )

迈德威视相机调用( 基于 Linux系统+ OpenCV )前言一、登录迈德威视官网,下载官方SDK二、代码调用与视频帧处理( 基于 OpenCV )总结 前言     此博客记录了迈德威视工业相机在 Linux 系统下的代码调用及其环境配置,通过 OpenCV 对视频帧进行处理。   一、登录迈德威视官网,下载官方SDK      迈德威视官网 : http://www.mindvision.com.cn/     1. 进入官网后,在服务支持中选择软件下载。    2. 选择Linux系统S.

kkkkkk0729的博客 5678

uniapp+openlayers集成天地图实战:renderjs通信陷阱与性能优化避坑指南

本文深入探讨了uniapp与openlayers集成天地图时的renderjs通信陷阱与性能优化策略。通过实战案例解析了renderjs的特殊通信机制、地图实例生命周期管理、图层懒加载等关键技巧,帮助开发者避免常见坑点,提升应用流畅度。特别针对多语言切换、热重载偏移等疑难问题提供了解决方案,是uniapp+openlayers开发者的实用避坑指南。

weixin_30872157的博客 362

基于SSM的“学生信息管理系统”的设计与实现(源码+数据库+文档)

随着计算机的迅猛发展,计算机在社会各个领域的应用正在得到加强,并且已经在商业,工业或政府部门中得到了广泛的使用,甚至教育行业也在将计算机应用于工作的各个方面。该毕业项目是将计算机应用于学校学生信息管理的示例。此设计使用MYSQL 5.5作为数据库,使用表达式作为开发工具,对教育系统中的学生信息进行数字管理。该系统可以减轻教职员工的工作压力,系统地比较教学工作和教学的各种服务和信息的管理,同时减少劳力使用,加快查询,加强管理和信息化。速度更加规范了各种管理。该系统具有更好的兼容性。

1481

Zemax操作41--公差分析(一)

zemax公差

lzy750750的博客 5973

学生信息管理系统说明

在MySQL中创建新的数据库sims,下载解压资源后将sims_backup.sql导入到sims中,在IDEA中打开项目,在JDBCUtils下修改自己MySQL的用户名及密码,成功保存后在SIMS\src\cn\test下运行Main.java即可正常运行系统。

x3308626949的博客 395

半导体功率器件IGBT工艺全流程

本文概述了功率器件IGBT(绝缘栅双极型晶体管)的关键制造流程。主要工艺包括:基板制备、离子注入(B+/P+/P+FS层)、绝缘膜形成与加工(CVD沉积及刻蚀)、沟槽刻蚀、电极形成(Emitter和Collector)等步骤。通过离子注入、化学气相沉积和物理气相沉积等半导体工艺,依次完成器件各功能层的构建,最终形成具备高功率特性的IGBT器件。该流程体现了功率半导体制造中典型的掺杂、薄膜沉积和图形化工艺技术。

750

AutoSAR EcuM系列01- EcuM模块的功能概述和变体类型

在【ECU的软硬件架构】文章中我们了解ECU的功能和组成,那么ECU具体是怎么启动的呢?我们知道,AutoSAR标准架构有三层,即APPL应用层、RTE层和BSW层。而这些层又被进一步划分为更多单独的组件,如BSW层可能有80多个组件。在ECU启动时,这些组件必须相互交互,有时也必须以某种顺序交互。这些组件的启动顺序由ECU管理器模块或EcuM处理。EcuM负责整个ECU的初始化和去初始化,包括对一些系统模块如。......

1766

学生信息管理系统(Python版),2024最新版,流程齐全,快来围观

学生信息管理系统为Python基础阶段知识的整合,在这一过程中可以增进对Python数据类型的理解,也可以对包、模块、函数等的相关知识进行巩固,对基础知识进行复盘,加深对Python语法的理解。

weixin_45938063的博客 3814

【通信协议】GATT 与 BLE HID 工作原理详解

详细介绍BLE HID 跟GATT工作原理与两者的交互关系

以实战经验介绍行业知识 843

用java开发学生信息管理系统(SIMS,一)

SIMS的开发需要java开发环境、数据库驱动、数据库。     一、数据库驱动     用java连接数据库得加载数据库驱动才行。SIMS是使用Mysql数据库的,所以要去官网把Mysql的数据库驱动下载过来,如下图:             1、单击Downloads,再单击MYSQL on Windows;             2、然后,再点击Mysql Connectors

白石雨的博客 2798

CAN轴控制流【6041,6040】

【代码】CAN轴控制流【6041,6040】

cfqq1989的博客 1783

【机器视觉】基于深度学习的托盘PCB识别与计数(有无、正反)

工业机器视觉是指在制造业和工业环境中使用计算机视觉技术来执行检测、测量、识别和控制任务。它结合了硬件(如相机、镜头、光源)与软件(图像处理算法)来自动完成传统上需要人工视觉的任务,从而提高生产效率、产品质量以及工作安全性。工业机器视觉系统通常具有高精度、高速度和高可靠性,能够适应恶劣的工作环境。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

学生信息管理系统的简单设计与实现 SIMS2.demo

基于s2sh的 学生信息管理系统的简单设计与实现 ----SIMS2.demo     ===查看图片附件===        系统架包           ----------------------------------------------------------------------------------------------- ...

temppad 305

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java新手实战:从零构建学生信息管理系统(SIMS)

在软件开发领域,数据管理是核心基础,而增删改查(CRUD)操作则是实现数据管理的基本功。其原理是通过对数据集合进行创建、读取、更新和删除,从而构建出具备完整业务逻辑的应用系统。掌握CRUD不仅有助于理解数据流动与状态变化,更是迈向合格开发者的关键一步。在Java开发中,面向对象编程、集合框架和异常处理等技术是实现CRUD的基石。通过一个具体的实战项目,如学生信息管理系统(SIMS),开发者能将分散的Java SE知识点串联起来,进行工程实践。该系统虽小,却涵盖了从数据模型设计、内存存储到初步分层架构(如MV

weixin_33796205的博客 400

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

用java开发学生信息管理系统(SIMS,二)

下面来做登陆这一块功能。新建SIMS项目,并把数据库驱动添加进项目里,然后新建all包、mainPro包、user包和View包,新建的包及类如下图:           一、all包,暂时有三个类。         connection类的来由,连接数据库很多地方都要用到,每一次连接数据库就要写上加载驱动和连接数据库的代码,这样代码就大量重复,另外如果数据库的密码临时改了

白石雨的博客 1950

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Python构建学生信息管理系统:设计学生信息管理系统的数据库

在本文中,我们设计了学生信息管理系统的数据库模型,包括必要的数据表和实体之间的关系

881

用java开发学生信息管理系统(SIMS,四)

这是学jdbc后做的第一个项目,有很多欠缺,在学习中慢慢成长。  现在来添加删除普通用户这个功能。         管理员点击“删除用户”进入删除用户所用的界面(showView类里关于界面的切换以后就不再介绍,SIMS界面切换的运作请参考之前几篇)。如下图         这个删除普通用户界面(userDestroy.java)有一个下拉列表,用于选择要删除的普通用户,当选择某一个用户

白石雨的博客 1496

链表实现:学生信息管理系统--SIMS

以下是要求: 1. Objective a) Learn how to define a structure; b) Describe the process of algorithm design and analysis; c) Learn how to use the fundamental linear data structures; d) Get familiar wit

海水梦悠悠的博客 1064

Python构建学生信息管理系统:搭建开发环境

在本文中,我们详细介绍了如何搭建Python虚拟环境,安装Flask框架,以及配置项目所需的依赖库。按照这些步骤,您应该能够成功搭建SIMS的开发环境,并为接下来的开发工作做好准备。如果您在搭建开发环境时遇到任何问题,请随时留言讨论。在接下来的系列文章中,我们将深入探讨如何实现学生信息管理系统的具体功能,敬请期待!

1229

python3参考秘籍附pdf下载

构建SIMS是一个复杂但充满成就感的过程。通过本系列博客,我们不仅学会了如何一步步构建一个完整的Web应用,还学习了如何将理论知识应用到实践中。在结束本系列博客之前,我们想强调,构建一个系统只是一个开始,持续的改进和维护才是确保系统长期可用的关键。希望本系列博客能够对您有所帮助,也欢迎您提出宝贵的意见和建议。

m0_60591287的博客 770

用java开发学生信息管理系统(SIMS,五)

管理员帐号与密码的修改相差不大,以修改管理员密码为例。         在user包下新建changeAdPassword类(changeAdPassword.java),此类有两个方法,一个是changeAdpw(String name,String pw),把管理员帐号和新密码作为参数传进去,就能修改此管理员的登陆密码;另一个方法是getAdpw(String name),把管理员帐号作

白石雨的博客 1453

SSH JavaWeb学生信息管理系统实现

上周周末断网。。。。。无聊的时候写的demo,SSH的。 SIMS(Student Information Management System,学生信息管理系统) 包括登录、学生信息录入,修改,删除,查询,数据批量导出等等功能。 开发环境:Eclipse ,jdk1.6 框架:SpringMvc+Hibernate(ORM工具) 前台:JSP 数据库:MySQL 众所周知,Spring

crazy_石头的专栏 1万+
RO0T
博客等级 码龄14年 1粉丝 1原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值