当前位置:网站首页>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;
}
边栏推荐
- Public Key Retrieval is not allowed(不允许公钥检索)【解决办法】
- 常用Anaconda安装错误解决办法Traceback (most recent call last):[通俗易懂]
- 七月券商金工精选
- Transferrin-modified vincristine-tetrandrine liposomes | transferrin-modified co-loaded paclitaxel and genistein liposomes (reagents)
- QoS服务质量七交换机拥塞管理
- flask装饰器版登录、session
- 优雅退出在Golang中的实现
- leetcode 547.省份数量 并查集
- Pt/CeO2单原子纳米酶|[email protected] NPs纳米酶|碳纳米管负载铂颗粒纳米酶|白血病拮抗多肽修饰的FeOPtPEG复合纳米酶
- 转铁蛋白修饰长春新碱-粉防己碱脂质体|转铁蛋白修饰共载紫杉醇和金雀异黄素脂质体(试剂)
猜你喜欢
从 GAN 到 WGAN
leetcode 547.省份数量 并查集
[email protected]纳米模拟酶|PtCo合金纳米粒子"/>
水溶性合金量子点纳米酶|CuMoS纳米酶|多孔硅基Pt(Au)纳米酶|[email protected]纳米模拟酶|PtCo合金纳米粒子
巧用RoaringBitMap处理海量数据内存diff问题
线性结构----链表
Metasploit——渗透攻击模块(Exploit)
[email prot"/>
Transferrin-modified osthole long-circulating liposomes/PEG-PLGA nanoparticles loaded with notoginsenoside R1 ([email prot
史上最全GIS相关软件(CAD、FME、Arcgis、ArcgisPro)
FEMRL: A Framework for Large-Scale Privacy-Preserving Linkage of Patients’ Electronic Health Rec Paper Summary
Colocate Join :ClickHouse的一种高性能分布式join查询模型
随机推荐
GBASE 8s 高可用RSS集群搭建
从 Delta 2.0 开始聊聊我们需要怎样的数据湖
Linux服务器安装Redis,详细步骤。
【Knowledge Sharing】What is SEI in the field of audio and video development?
子域名收集&Google搜索引擎语法
关于npm/cnpm/npx/pnpm与yarn
Introduction to 3 d games beginners essential 】 【 modeling knowledge
opengrok搭建[通俗易懂]
端口探测详解
cordova 安装错误 Command failed: powershell 解决方法
zip文件协议解析
这7个自动化办公模版 教你玩转表格数据自动化
Tf铁蛋白颗粒包载顺铂/奥沙利铂/阿霉素/甲氨蝶呤MTX/紫杉醇PTX等药物
铱钌合金/氧化铱仿生纳米酶|钯纳米酶|GMP-Pd纳米酶|金钯复合纳米酶|三元金属Pd-M-Ir纳米酶|中空金铂合金纳米笼核-多空二氧化硅壳纳米酶
idea汉化教程[通俗易懂]
uni-app 数据上拉加载更多功能
怎么完全卸载赛门铁克_Symantec卸载方法,赛门铁克卸载「建议收藏」
今日份bug,点击win10任务栏视窗动态壁纸消失的bug,暂未发现解决方法。
spark学习笔记(九)——sparkSQL核心编程-DataFrame/DataSet/DF、DS、RDD三者之间的转换关系
ARouter使用自定义注解处理器,自动生成跳转Activity的代码,避免手动填写和管理path