当前位置:网站首页>C语言写数据库
C语言写数据库
2022-08-10 19:12:00 【渣渣馬】
//直接上代码 \ C语言写数据库
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h> //断言函数的库
#include<errno.h> //错误机制库
#define MAX_DATA 512
#define MAX_ROWS 100
struct Adress{
int id;
int set;
char name[MAX_DATA];
char email[MAX_ROWS];
};
struct Database{
struct Adress rows[MAX_ROWS];
};
struct Connection{
FILE* file;
struct Database* db;
};
void die(const char* message){
if(errno){
//发生错误时该error的变量值为1,可通过perror打印出错信息
perror(message); //和printf的作用差不多,只是它使用在错误的时候打印
}else{
printf("ERROR:%s\n",message);
}
exit(1); //不正常程序退出
}
void Adress_print(struct Adress* addr){
printf("%d %s %s\n",addr->id,addr->name,addr->email);
}
void Database_load(struct Connection* conn){
//fread函数:将file指针指向的内容读取1个数据块,大小为sizeof那么大的数据块,给db指针; \ 返回数据块指定个数表示成功;反之读取失败。
int rc=fread(conn->db,sizeof(struct Database),1,conn->file);
if(rc != 1)
die("Failed to load database.");
}
struct Connection* Database_open(const char* filename,char mode){
struct Connection* conn=malloc(sizeof(struct Connection));
if(!conn) //NULL的宏定义本质是0
die("Memory error");
conn->db=malloc(sizeof(struct Database));
if(!conn)
die("Memory error");
if(mode == 'c'){
conn->file =fopen(filename,"w");
}else{
conn->file =fopen(filename,"r+"); //读取已存在的文件,光标到开头
if(conn->file){
Database_load(conn);
}
}
if(!conn->file)
die("Failed to open the file");
return conn;
}
//释放资源的时候,应该先放“子资源”,再放“父资源”;防止出现野地址(野内存,无法认领或访问的内存)
void Database_close(struct Connection* conn){
if(conn){
if(conn->file)
fclose(conn->file);
if(conn->db)
free(conn->db);
free(conn);
}
}
void Database_write(struct Connection* conn){
rewind(conn->file); //rewind函数:文件I/O流的指针回归文件开头
//将若干数据块写入指定文件,写入file文件指针
int rc=fwrite(conn->db,sizeof(struct Database),1,conn->file);
if(rc != 1)
die("Failed to write database.");
rc=fflush(conn->file); //清除缓存I/O流
if(rc == -1)
die("Cannot flush database.");
}
void Database_create(struct Connection* conn){
int i=0;
for(i=0;i<MAX_ROWS;i++){
struct Adress addr={
.id=i,.set=0};
conn->db->rows[i]=addr;
}
}
void Database_set(struct Connection* conn,int id,const char* name,const char* email){
struct Adress* addr=&conn->db->rows[id];
if(addr->set)
die("Already set,delete it first");
addr->set=1;
char* res=strncpy(addr->name,name,MAX_DATA);
if(!res)
die("Name copy failed");
}
void Database_get(struct Connection* conn,int id){
struct Adress* addr=&conn->db->rows[id];
if(addr->set){
Adress_print(addr);
}else{
die("ID is not set");
}
}
void Database_delete(struct Connection* conn,int id){
struct Adress addr={
.id=id,.set=0}; //结构体的默认赋值方法,可以省略结构体名
conn->db->rows[id]=addr; //当结构体嵌套时候,应该搞清对应关系,避免指向再指向的问题
}
void Database_list(struct Connection* conn){
int i=0;
struct Database* db=conn->db;
for(i=0;i<MAX_ROWS;i++){
struct Adress* cur=&db->rows[i];
if(cur->set)
Adress_print(cur);
}
}
int main(int argc,char* argv[]){
if(argc<3)
die("USAGE:ex17 <dbfile><action> [action params]");
char* filename=argv[1];
char action=argv[2][0];
struct Connection* conn=Database_open(filename,action);
int id=0;
if(argc>3) id=atoi(argv[3]); //将字符转换成int型
if(id>MAX_ROWS) die("There`s not that many records.");
switch(action){
case 'c':
Database_create(conn);
Database_write(conn);
break;
case 'g':
if(argc!=4)
die("Need an id to get");
Database_get(conn,id);
break;
case 's':
if(argc!=6)
die("Need an id ,name,email to set");
Database_set(conn,id,argv[4],argv[5]);
Database_write(conn);
break;
case 'd':
if(argc!=4)
die("Need an id to delete");
Database_delete(conn,id);
Database_write(conn);
break;
case 'l':
Database_list(conn);
break;
default:die("Invalid action: c=create,g=get,s=set,d=del,l=list");
}
Database_close(conn);
return 0;
}
边栏推荐
- Introduction to 3 d games beginners essential 】 【 modeling knowledge
- 【C#】WCF和TCP消息通信练习,实现群聊功能
- 铁蛋白颗粒Tf包载多肽/凝集素/细胞色素C/超氧化物歧化酶/多柔比星(定制服务)
- 机器学习|模型评估——AUC
- 关于npm/cnpm/npx/pnpm与yarn
- 『牛客|每日一题』岛屿数量
- Solution for thread not gc-safe when Rider debugs ASP.NET Core
- redis如何查看key的有效期
- 血红素-金纳米颗粒(Heme-AuNP)复合纳米酶|金纳米颗粒核多孔空心碳纳米球壳([email protected])纳米酶
- 3D游戏建模学习路线
猜你喜欢
[email prot"/>
Transferrin-modified osthole long-circulating liposomes/PEG-PLGA nanoparticles loaded with notoginsenoside R1 ([email prot
mysql踩坑----case when then用法
[email protected])纳米酶"/>
血红素-金纳米颗粒(Heme-AuNP)复合纳米酶|金纳米颗粒核多孔空心碳纳米球壳([email protected])纳米酶
Common ports and services
ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path
Optimizing Bloom Filter: Challenges, Solutions, and Comparisons论文总结
[email protected] nanomimetic e"/>
Water-soluble alloy quantum dot nanozymes|CuMoS nanozymes|porous silicon-based Pt(Au) nanozymes|[email protected] nanomimetic e
uni-app 数据上拉加载更多功能
Solution for thread not gc-safe when Rider debugs ASP.NET Core
Linux服务器安装Redis,详细步骤。
随机推荐
不止跑路,拯救误操作rm -rf /*的小伙儿
idea汉化教程[通俗易懂]
电脑如何去掉u盘写保护的状态
[CNN] Brush SOTA's trick
我们用48h,合作创造了一款Web游戏:Dice Crush,参加国际赛事
[Go WebSocket] 你的第一个Go WebSocket服务: echo server
3D Game Modeling Learning Route
皮质-皮质网络的多尺度交流
赎金信问题答记
越折腾越好用的 3 款开源 APP
转铁蛋白修饰长春新碱-粉防己碱脂质体|转铁蛋白修饰共载紫杉醇和金雀异黄素脂质体(试剂)
主动信息收集
When selecting a data destination when creating an offline synchronization node - an error is reported in the table, the database type is adb pg, what should I do?
QoS服务质量六路由器拥塞管理
Site Architecture Detection & Chrome Plugin for Information Gathering
【CNN】刷SOTA的trick
血红素-金纳米颗粒(Heme-AuNP)复合纳米酶|金纳米颗粒核多孔空心碳纳米球壳([email protected])纳米酶
网站架构探测&chrome插件用于信息收集
servlet映射路径匹配解析
echart 特例-多分组X轴