想象一下你正在经营一家小型书店,以前,你用厚厚的账本记录每本书的信息——书名、作者、价格、库存量,每次有新书到货,你得手动添加一行;书卖掉了,要划掉一行;价格调整时,还得用涂改液修改...
你决定用C语言把这些数据搬到电脑里管理,这不就是数据库表(table)的典型应用场景吗?让我们一起来看看如何用C语言实现数据库表的基本操作:增(Insert)、删(Delete)、改(Update)、查(Select),也就是俗称的"CRUD"操作。
在开始编码前,我们需要明确几个概念:
// 以书店为例,我们定义一个简单的图书表结构 typedef struct { int id; // 主键,唯一标识 char title[100]; // 书名 char author[50]; // 作者 float price; // 价格 int stock; // 库存量 } Book;
这个结构体就相当于数据库中的一个表(table),每个字段(成员变量)对应表中的一列,每本书的信息就是表中的一行记录。
在真正的数据库系统中,我们会用CREATE TABLE语句,在C语言中,我们可以用文件来模拟:
#include <stdio.h> #include <string.h> // 初始化数据库文件(创建表) void create_table(const char* filename) { FILE* file = fopen(filename, "wb"); // 以二进制写入模式打开 if (file == NULL) { perror("无法创建表文件"); return; } // 可以在这里写入文件头信息,比如版本号、记录数等 int record_count = 0; fwrite(&record_count, sizeof(int), 1, file); fclose(file); printf("表创建成功: %s\n", filename); }
新书到货了,我们需要把它添加到"表"中:
// 向表中插入一条新记录 void insert_record(const char* filename, Book* new_book) { FILE* file = fopen(filename, "r+b"); // 读写模式打开 if (file == NULL) { perror("无法打开表文件"); return; } // 读取当前记录数 int record_count; fread(&record_count, sizeof(int), 1, file); // 设置新记录的ID(自动递增) new_book->id = record_count + 1; // 移动到文件末尾 fseek(file, 0, SEEK_END); // 写入新记录 fwrite(new_book, sizeof(Book), 1, file); // 更新记录数 record_count++; fseek(file, 0, SEEK_SET); fwrite(&record_count, sizeof(int), 1, file); fclose(file); printf("成功添加新书: %s\n", new_book->title); }
使用示例:
Book new_book = {= "C程序设计语言", .author = "K&R", .price = 59.9, .stock = 10 }; insert_record("bookstore.dat", &new_book);
顾客来问某本书的信息,我们需要从"表"中查找:
// 根据ID查询记录 Book* select_by_id(const char* filename, int id) { FILE* file = fopen(filename, "rb"); if (file == NULL) { perror("无法打开表文件"); return NULL; } // 读取记录数 int record_count; fread(&record_count, sizeof(int), 1, file); if (id <= 0 || id > record_count) { printf("无效的ID\n"); fclose(file); return NULL; } // 定位到指定记录 fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET); Book* result = malloc(sizeof(Book)); if (fread(result, sizeof(Book), 1, file) != 1) { free(result); fclose(file); return NULL; } fclose(file); return result; } // 打印查询结果 void print_book(Book* book) { if (book == NULL) { printf("未找到指定图书\n"); return; } printf("ID: %d\n", book->id); printf("书名: %s\n", book->title); printf("作者: %s\n", book->author); printf("价格: %.2f\n", book->price); printf("库存: %d\n", book->stock); printf("-------------------\n"); }
使用示例:
Book* book = select_by_id("bookstore.dat", 1); print_book(book); free(book); // 记得释放内存
某本书价格调整了,我们需要更新记录:
// 更新记录 void update_record(const char* filename, int id, Book* updated_book) { FILE* file = fopen(filename, "r+b"); if (file == NULL) { perror("无法打开表文件"); return; } // 读取记录数 int record_count; fread(&record_count, sizeof(int), 1, file); if (id <= 0 || id > record_count) { printf("无效的ID\n"); fclose(file); return; } // 定位到指定记录 fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET); // 保留原始ID updated_book->id = id; // 更新记录 if (fwrite(updated_book, sizeof(Book), 1, file) != 1) { perror("更新记录失败"); } else { printf("成功更新ID为%d的记录\n", id); } fclose(file); }
使用示例:
Book updated_info = {= "C程序设计语言(新版)", .author = "K&R", .price = 69.9, // 价格从59.9调整到69.9 .stock = 8 // 卖出了2本 }; update_record("bookstore.dat", 1, &updated_info);
某本书不再销售了,我们需要从"表"中删除:
// 删除记录(逻辑删除) void delete_record(const char* filename, int id) { FILE* file = fopen(filename, "r+b"); if (file == NULL) { perror("无法打开表文件"); return; } // 读取记录数 int record_count; fread(&record_count, sizeof(int), 1, file); if (id <= 0 || id > record_count) { printf("无效的ID\n"); fclose(file); return; } // 定位到指定记录 fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET); // 标记为删除(这里简单地将ID设为-1作为删除标记) Book deleted_book; fread(&deleted_book, sizeof(Book), 1, file); deleted_book.id = -1; fseek(file, -sizeof(Book), SEEK_CUR); fwrite(&deleted_book, sizeof(Book), 1, file); fclose(file); printf("已标记删除ID为%d的记录\n", id); }
注意:在实际应用中,我们通常不会真正从文件中删除数据,而是采用"逻辑删除"(标记删除)的方式,或者使用更复杂的数据结构来管理。
顾客想找所有价格低于50元的书,我们需要实现条件查询:
// 条件查询(价格低于指定值) void select_by_price(const char* filename, float max_price) { FILE* file = fopen(filename, "rb"); if (file == NULL) { perror("无法打开表文件"); return; } // 读取记录数 int record_count; fread(&record_count, sizeof(int), 1, file); printf("价格低于%.2f的图书:\n", max_price); printf("-------------------\n"); Book current; int found = 0; for (int i = 0; i < record_count; i++) { fread(¤t, sizeof(Book), 1, file); // 跳过已删除的记录 if (current.id == -1) continue; if (current.price < max_price) { print_book(¤t); found++; } } if (!found) { printf("未找到符合条件的图书\n"); } fclose(file); }
使用示例:
select_by_price("bookstore.dat", 50.0);
把上面的功能整合起来,我们可以构建一个简单的命令行书店管理系统:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int id; char title[100]; char author[50]; float price; int stock; } Book; // 省略之前的函数实现... int main() { const char* filename = "bookstore.dat"; // 初始化表(如果不存在) FILE* test = fopen(filename, "rb"); if (test == NULL) { create_table(filename); } else { fclose(test); } // 简单命令行界面 int choice; do { printf("\n书店管理系统\n"); printf("1. 添加新书\n"); printf("2. 查询图书\n"); printf("3. 更新图书信息\n"); printf("4. 删除图书\n"); printf("5. 按价格搜索\n"); printf("0. 退出\n"); printf("请选择操作: "); scanf("%d", &choice); switch (choice) { case 1: { Book new_book; printf("请输入书名: "); scanf(" %[^\n]", new_book.title); printf("请输入作者: "); scanf(" %[^\n]", new_book.author); printf("请输入价格: "); scanf("%f", &new_book.price); printf("请输入库存量: "); scanf("%d", &new_book.stock); insert_record(filename, &new_book); break; } case 2: { int id; printf("请输入要查询的图书ID: "); scanf("%d", &id); Book* book = select_by_id(filename, id); print_book(book); if (book != NULL) free(book); break; } case 3: { int id; printf("请输入要更新的图书ID: "); scanf("%d", &id); Book updated; printf("请输入新书名: "); scanf(" %[^\n]", updated.title); printf("请输入新作者: "); scanf(" %[^\n]", updated.author); printf("请输入新价格: "); scanf("%f", &updated.price); printf("请输入新库存量: "); scanf("%d", &updated.stock); update_record(filename, id, &updated); break; } case 4: { int id; printf("请输入要删除的图书ID: "); scanf("%d", &id); delete_record(filename, id); break; } case 5: { float price; printf("请输入最高价格: "); scanf("%f", &price); select_by_price(filename, price); break; } case 0: printf("感谢使用书店管理系统\n"); break; default: printf("无效的选择,请重新输入\n"); } } while (choice != 0); return 0; }
通过这个简单的例子,我们展示了如何用C语言实现数据库表的基本操作,虽然这只是一个简化版本,但它涵盖了数据库系统的核心概念:
在实际的数据库系统中,这些操作会更加复杂和高效,但基本原理是相通的,理解这些基础操作后,你就能更好地使用真正的数据库系统,或者根据需求开发自己的轻量级数据存储解决方案。
好的数据库设计是应用成功的关键,在你开始编码前,花时间规划好表结构和关系,这将为你省去后续许多麻烦。
本文由 但访天 于2025-08-06发表在【云服务器提供商】,文中图片由(但访天)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://up.7tqx.com/wenda/552372.html
发表评论