OSTEP Projects:KV
本文将介绍操作系统导论(Operating Systems: Three Easy Pieces)作者所开源的操作系统相关课程项目 的 KV 部分,包含个人的代码实现和设计思路。
思路
题目要求实现一个最简单的数据库,以支持数据的持久化。
每个操作由格式为 op,[arg1],[arg2] 的命令给出,那么首先要解决的问题就是参数的分离,再根据操作符 op 来对不同的操作进行特殊处理。字符串划分这里采用的是 strsep() 函数:该函数接收两个参数 char** stringp 和 const char* delim,stringp 是指向待分割字符串 string 的指针,delim 则是指定的分隔符,该函数的操作是查找 string 中第一个 delim 的位置 it,并将 stringp 指向 string 中 it + 1 的位置,同时返回string 开头到 it 所有字符所构成的子串(加上 '\0' 终结符)。
插入操作没什么好说的,直接使用 fprintf() 写入文件即可。对于查找和删除,则需要将数据从文件(数据库)中读取到内存,存储在特定的数据结构中,例如哈希表、红黑树等,但为了代码实现的简单,我使用的是最简单的链表。对于查找,先将所有数据读取到一个链表中,然后按顺序逐个进行查找;对于删除,将所有数据读取到一个链表中,然后逐个遍历链表,如果当前结点的键(key)与参数不同,则写入文件中,否则,不写入(相当于删除)。最后,为了防止内存的泄露,需要在每次结束查找和删除操作之后,将存储数据内容的链表结点的内存空间释放。
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define DATA_BASE "./database.txt"typedef struct LineNode {char* line_buf;struct LineNode* next;
} line_node;// 从文件fp中读取数据
line_node* read_from_file(FILE* fp) {line_node* dummy = (line_node*)malloc(sizeof(line_node)); // 哨兵结点line_node* p = dummy;size_t sz = 0;while (1) {p->next = (line_node*)malloc(sizeof(line_node));p = p->next;if (getline(&(p->line_buf), &sz, fp) == -1) {p->next = NULL;break;}}return dummy->next;
}// 释放链表内存空间
void free_list_mem(line_node* data) {while (data != NULL) {line_node* temp = data;data = data->next;free(temp);}
}int main(int argc, char* argv[]) {for (int i = 1; i < argc; ++i) {char* op = strsep(&argv[i], ","); // 操作符if (!strcmp(op, "p")) {char* key = strsep(&argv[i], ",");char* value = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "a");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fprintf(fp, "%s,%s\n", key, value);fclose(fp);}else if (!strcmp(op, "g")) {char* key = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* data = read_from_file(fp);line_node* p = data;int flag = 0;while (p != NULL) {char* entry = strdup(p->line_buf); // 条目备份(line_buf会被strsep()修改)char* token = strsep(&(p->line_buf), ",");if (!strcmp(token, key)) { // 找到keyflag = 1;printf("%s", entry);break;}p = p->next;}if (!flag) {printf("%s not found\n", key);}free_list_mem(data);fclose(fp);}else if (!strcmp(op, "d")) {char* key = strsep(&argv[i], ",");if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* data = read_from_file(fp);fclose(fp);// 清空文件fp = fopen(DATA_BASE, "w");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fclose(fp);fp = fopen(DATA_BASE, "a");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}line_node* p = data;while (p != NULL) {char* entry = strdup(p->line_buf); // 条目备份char* token = strsep(&(p->line_buf), ",");if (strcmp(token, key)) { // 当前条目键值为key,不写入(相当于删除)fprintf(fp, "%s", entry);}p = p->next;}free_list_mem(data);fclose(fp);}else if (!strcmp(op, "c")) {if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "w");if (fp == NULL) {fprintf(stderr, "cannot open file %s\n", DATA_BASE);exit(1);}fclose(fp);}else if (!strcmp(op, "a")) {if (argv[i] != NULL) {printf("bad command\n");continue;}FILE* fp = fopen(DATA_BASE, "r");line_node* data = read_from_file(fp);line_node* p = data;while (p != NULL) {printf("%s", p->line_buf);p = p->next;}free_list_mem(data);fclose(fp);}else {printf("bad command\n");continue;}}return 0;
}
相关文章:
OSTEP Projects:KV
本文将介绍操作系统导论(Operating Systems: Three Easy Pieces)作者所开源的操作系统相关课程项目 的 KV 部分,包含个人的代码实现和设计思路。 思路 题目要求实现一个最简单的数据库,以支持数据的持久化。 每个操作由格式为 o…...
JAVA学习笔记(第三周)
文章目录 继承概述使用场景继承的特点子类继承的内容成员变量访问特点成员方法访问特点方法的重写构造方法this super 多态多态的表现形式多态的前提成员变量和方法调用instanceof优势弊端 包包名的规则全类名final常量 权限修饰符代码块 继承 概述 继承就是子类继承父类的特征…...
linux 内核驱动 -- reboot -f 导致内核死机 而 reboot则不会引起问题
问题描述,定于与解决:...
【vue-echarts】 报错问题解决 “Error: Component series.pie not exists. Load it first.“
目录 问题描述解决【解决1】【解决2】 问题描述 使用 vue-echarts 时导入的文件 import VChart from vue-echarts/components/ECharts import echarts/lib/chart/line import echarts/lib/chart/bar import echarts/lib/chart/pie import echarts/lib/component/legend impor…...
MySQL慢查询SQL优化
一、慢查询日志 描述:通过慢查询日志等定位那些执行效率较低的SQL语句 查看 # 慢查询是否开启 show variables like slow_query_log%; # 慢查询超时时间 show variables like long_query_time%;执行SQL 开启慢查询日志 set global slow_query_log ON;设置慢查…...
【嵌入式DIY实例】-DDS信号生成器
DDS信号生成器 文章目录 DDS信号生成器1、AD9805介绍2、硬件准备与接线3、代码实现在本文中,将详细介绍如何使用AD9850来搭建一个简易的DDS(Direct Digital signal )信号生成器。 1、AD9805介绍 AD9850是一款高度集成的器件,采用先进的DDS技术,内置一个高速、高性能数模转…...
java设计模式四 桥接模式
桥接模式关注于将抽象部分与实现部分分离,使它们可以独立变化。它通过在抽象和实现之间建立一个桥梁来实现这一目的。这种设计模式属于结构型模式。 假设我们要设计一个图形编辑器,其中图形(如圆形、正方形)可以有不同的颜色填充…...
《Python编程从入门到实践》day24
# 昨日知识点学习 创建外星人从一个到一行 # 主程序snipdef _create_fleet(self):"""创建外星人群"""# 创建一个外星人并计算一行可容纳多少个外星人# 外星人的间距为外星人的宽度alien Alien(self)alien_width alien.rect.widthavailable_sp…...
【hackmyvm】 Animetronic靶机
靶机测试 arp-scanporturl枚举exiftool套中套passwordsudo 提权 arp-scan arp-scan 检测局域网中活动的主机 192.168.9.203 靶机IP地址port 通过nmap扫描,获取目标主机的端口信息 ┌──(root㉿kali)-[/usr/share/seclists] └─# nmap -sT -sV -O 192.16…...
[附源码]石器时代_恐龙宝贝内购版_三网H5手游_带GM工具
石器时代之恐龙宝贝内购版_三网H5经典怀旧Q萌全网通手游_Linux服务端源码_视频架设教程_GM多功能授权后台_CDK授权后台 本教程仅限学习使用,禁止商用,一切后果与本人无关,此声明具有法律效应!!!࿰…...
RS2255XN功能和参数介绍及PDF资料
RS2255XN是一款由Runic(润石)公司生产的模拟开关。以下是关于RS2255XN的一些技术参数和特点: 封装:MSOP-10 电源电压范围:2.5V至5.5V 工作温度范围:-40C至125C 类型:模拟开关 品牌:R…...
设计模式——外观模式(Facade)
外观模式(Facade Pattern) 是一种结构型设计模式,它为一个子系统中的一组接口提供一个统一的高层接口,使得子系统更加容易使用。这种类型的设计模式属于结构型模式,它向客户端提供了一个接口,隐藏了子系统的…...
【linux软件基础知识】Linux 中的普通进程的调度机制
活动集Active processes和过期集Expired processes 为了实现静态优先级较低的进程没有完全锁定并有机会运行,Linux 调度程序维护两个不相交的可运行进程集:活动集和过期集。 此机制是完全公平调度程序 (CFS) 算法的一部分。 以下是这两组的工作原理: 活动集Active proces…...
keil5软件安装教程(MDKv5.39)
keil5软件安装分为三部分: 目录 1.安装mdk 2.激活mdk 3.安装STM32芯片包 1.安装mdk 安装包链接:链接:https://pan.baidu.com/s/1PZoGhzI5Y19ROv7xe9QJKA?pwdgt3s 提取码:gt3s 1、下载keil5的压缩包并解压,鼠…...
改变视觉创造力:图像合成中基于样式的生成架构的影响和创新
原文地址:revolutionizing-visual-creativity-the-impact-and-innovations-of-style-based-generative 2024 年 4 月 30 日 介绍 基于风格的生成架构已经开辟了一个利基市场,它将机器学习的技术严谨性与类人创造力的微妙表现力融为一体。这一发展的核…...
【LAMMPS学习】八、基础知识(5.8)LAMMPS 中热化 Drude 振荡器教程
8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…...
基于SpringBoot的全国风景区WebGIS按省展示实践
目录 前言 一、全国风景区信息介绍 1、全国范围内数据分布 2、全国风景区分布 3、PostGIS空间关联查询 二、后台查询的设计与实现 1、Model和Mapper层 2、业务层和控制层设计 三、WebGIS可视化 1、省份范围可视化 2、省级风景区可视化展示 3、成果展示 总结 前…...
深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】
文章目录 前言TCP协议段格式一、确认应答【保证可靠性传输的机制】二、超时重传【保证可靠性传输的机制】三、连接管理机制【保证可靠性传输的机制】3.1建立连接(TCP三次握手)---经典面试题3.2断开连接(四次挥手)3.3TCP状态转换 四…...
Java并发编程之锁的艺术:面试与实战指南(三)
Java并发编程之锁的艺术:面试与实战指南(三) 文章目录 Java并发编程之锁的艺术:面试与实战指南(三)前言十七、Java中线程和进程的区别是什么?十八、什么是Java内存模型(JMMÿ…...
Final Draft 12 for Mac:高效专业剧本创作软件
对于剧本创作者来说,一款高效、专业的写作工具是不可或缺的。Final Draft 12 for Mac就是这样一款完美的选择。这款专为Mac用户设计的剧本创作软件,凭借其卓越的性能和丰富的功能,让您的剧本创作更加得心应手。 Final Draft 12支持多种剧本格…...
AgentCPM-Report研报系统实操:Pixel Epic贤者响应延迟优化教程
AgentCPM-Report研报系统实操:Pixel Epic贤者响应延迟优化教程 1. 认识Pixel Epic智识终端 Pixel Epic是一款基于AgentCPM-Report大模型构建的创新研究报告辅助系统。与传统AI工具不同,它将枯燥的科研过程转化为一场像素风格的RPG冒险。在这个系统中&a…...
Visio高效绘制神经网络卷积层:从基础到三维呈现
1. Visio绘制神经网络卷积层的入门指南 第一次用Visio画神经网络结构时,我盯着满屏的工具栏发懵——这玩意儿比Photoshop的图层还复杂。但摸索半天后发现,只要掌握几个核心功能,画卷积层其实比用PPT简单十倍。先说说最基础的形状选择…...
深入解析Nordic NRF52832的NFC天线与GPIO复用设计
1. NFC天线硬件设计基础 NRF52832芯片的NFC功能通过P0.09和P0.10两个专用引脚实现,这两个引脚在设计时需要特别注意硬件连接规范。实际项目中,我遇到过不少开发者直接将这两个引脚当作普通GPIO使用导致通信异常的情况——因为默认状态下它们被硬件映射为…...
基于大数据技术的产品评价分析系统设计与实现
前言本研究聚焦于设计与实现一种基于大数据技术的产品评价分析系统,通过构建多层架构体系与融合多元技术方法,为企业决策提供智能化支撑。 研究采用分层架构设计理念,将系统划分为数据采集、存储、处理、分析与展示五大模块。数据采集层综合运…...
Web3D开发入门:5大引擎(Direct3D、OpenGL、UE、Unity、Three.js)选型指南
Web3D开发入门:5大引擎选型实战指南 当虚拟展厅、数字孪生和元宇宙应用席卷各行业时,选择合适的三维引擎成为开发者面临的首个关键决策。本文将带您深入剖析Direct3D、OpenGL、Unreal Engine、Unity和Three.js五大主流方案的技术特性与商业价值ÿ…...
从零构建树莓派人脸识别门禁:硬件选型、环境部署与实战避坑
1. 硬件选型与采购清单 第一次玩树莓派人脸识别项目时,我在淘宝上花了整整三天对比各种硬件参数。当时最纠结的就是摄像头模块——普通USB摄像头才30块钱,而官方推荐的Raspberry Pi Camera Module V2要200多。后来实测发现,这差价真不能省。 …...
OBS多平台直播同步解决方案:从配置到优化的完整指南
OBS多平台直播同步解决方案:从配置到优化的完整指南 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 在当今内容创作领域,多平台同步直播已成为扩大受众覆盖的关键…...
高效开源输入法词库转换实战指南:30+格式无缝互转技巧
高效开源输入法词库转换实战指南:30格式无缝互转技巧 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 深蓝词库转换是一款功能强大的开源输入法词库转换工…...
图图的嗨丝造相-Z-Image-Turbo效果对比:8bit vs 16bit精度推理对渔网袜边缘锐度的影响
图图的嗨丝造相-Z-Image-Turbo效果对比:8bit vs 16bit精度推理对渔网袜边缘锐度的影响 1. 引言:当AI绘画遇上“渔网袜”细节 最近在玩一个挺有意思的AI绘画模型——图图的嗨丝造相-Z-Image-Turbo。这个模型专门针对“大网渔网袜”这种特定服饰的生成做…...
Android位置模拟与GPS伪装:基于Xposed模块的场景化解决方案
Android位置模拟与GPS伪装:基于Xposed模块的场景化解决方案 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 在移动应用开发与隐私保护领域,位置信息的精准…...
