0820 SQlite与c语言的结合
Part 1.牛客网刷题
Part 2.停车系统
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sqlite3.h>int msg_ins(sqlite3 *ppdb)
{char carnumber[128] = "";printf("请输入入库车牌\n");scanf(" %s", carnumber);time_t intime = time(NULL);char sql[256] = "";sprintf(sql, "insert into PART(carnumber, intime) values(\"%s\", %ld);", carnumber, intime);char *errmsg = NULL;if(sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("msg_ins error:%s\n", errmsg);sqlite3_free(errmsg);return -1;}printf("车牌 %s 已入库\n", carnumber);return 0;
}int msg_upd(sqlite3 *ppdb)
{char carnumber[128] = "";printf("请输入出库车牌\n");scanf(" %s", carnumber);// 先查询入库时间char sql[256] = "";sprintf(sql, "select intime from PART where carnumber = \"%s\" and outtime = 0;", carnumber);char *errmsg = NULL;sqlite3_stmt *stmt;if(sqlite3_prepare_v2(ppdb, sql, -1, &stmt, NULL) != SQLITE_OK){printf("查询错误: %s\n", sqlite3_errmsg(ppdb));return -1;}if(sqlite3_step(stmt) != SQLITE_ROW){printf("未找到该车牌或车辆已出库\n");sqlite3_finalize(stmt);return -1;}time_t intime = sqlite3_column_int64(stmt, 0);sqlite3_finalize(stmt);time_t outtime = time(NULL);double duration = difftime(outtime, intime); // 停车时长(秒)double hours = duration / 3600.0; // 转换为小时// 计算费用 (假设每小时5元,不足1小时按1小时计算)double coast = (int)(hours) + (hours > (int)hours ? 1 : 0);coast *= 5.0;// 更新出库时间和费用sprintf(sql, "update PART set outtime = %ld, coast = %.2f where carnumber = \"%s\" and outtime = 0;", outtime, coast, carnumber);if(sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("msg_upd error:%s\n", errmsg);sqlite3_free(errmsg);return -1;}// 显示停车信息和费用printf("车牌: %s\n", carnumber);printf("入库时间: %s", ctime(&intime));printf("出库时间: %s", ctime(&outtime));printf("停车时长: %.2f 小时\n", hours);printf("费用: %.2f 元\n", coast);return 0;
}int callback(void *arg, int cols, char **col_text, char **col_name)
{if (*(int *)arg == 0){for(int i = 0; i < cols; i++){printf("%-15s", col_name[i]);}printf("\n");*(int *)arg = 1;}for(int i = 0; i < cols; i++){if(i == 1 || i == 2) // 时间字段{if(col_text[i] == NULL || atol(col_text[i]) == 0) {printf("%-15s", "未出库");}else{time_t timestamp = atol(col_text[i]); struct tm *p = localtime(×tamp); if(p != NULL)printf("%02d:%02d:%02d ", p->tm_hour, p->tm_min, p->tm_sec);elseprintf("%-15s", "时间错误");}}else if(i == 3) // 费用字段{if(col_text[i] == NULL || atof(col_text[i]) == 0)printf("%-15s", "未计费");elseprintf("%-15.2f", atof(col_text[i]));}else{printf("%-15s", col_text[i] ? col_text[i] : "NULL");}}printf("\n");return 0;
}int msg_sel(sqlite3 *ppdb)
{char sql[128] = "select * from PART;";char *errmsg = NULL;int flag = 0;printf("\n当前停车信息:\n");if(sqlite3_exec(ppdb, sql, callback, &flag, &errmsg) != SQLITE_OK){printf("msg_sel error:%s\n", errmsg);sqlite3_free(errmsg);return -1;}return 0;
}int main(int argc, const char *argv[])
{sqlite3 *ppdb = NULL;if(sqlite3_open("./db.db", &ppdb) != SQLITE_OK){printf("sqlite3_open error errcode = %d, errmsg = %s\n", sqlite3_errcode(ppdb), sqlite3_errmsg(ppdb));return -1;}char *sql = "create table if not exists PART(carnumber text PRIMARY KEY, intime int, outtime int default 0, coast float default 0);";char *errmsg = NULL;if(sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("table create error: %s\n", errmsg);sqlite3_free(errmsg);sqlite3_close(ppdb);return -1;}int menu = -1;while(1){system("clear");printf("----------停车收费管理系统---------\n");printf("----------1.汽车入库---------------\n");printf("----------2.汽车出库并计算费用-----\n");printf("----------3.查看所有停车位信息-----\n");printf("----------0.退出汽车入库系统-------\n");printf("请选择你要进行的操作: ");scanf(" %d", &menu);switch(menu){case 1:msg_ins(ppdb);break;case 2:msg_upd(ppdb);break;case 3:msg_sel(ppdb);break;case 0:sqlite3_close(ppdb);exit(EXIT_SUCCESS);default:printf("无效选项,请重新选择!\n");}if(menu != 0){printf("\n按回车键继续...");while(getchar() != '\n'); // 清空输入缓冲区getchar(); // 等待用户按回车}}return 0;
}
Part 3.梳理知识点
一.sql语句
1.create table
功能:创建数据库表格
原型:create table 表名 (字段名 数据类型, 字段名 数据类型);
例子:CREATE TABLE if not exists stu1 (id int, name char, score float);
2.insert into
功能:插入数据
原型:insert into 表名 values (数据1, 数据2, 数据3);
例子:INSERT INTO stu VALUES (1, "zs", 59);
3.select from
功能:查看数据
原型:select * form 表名 where 条件
例子:SELECT * FROM stu WHERE id<3 AND score>90;
4.delete from
功能:删除数据
原型:delete from 表名 where 条件
例子:DELETE FROM stu WHERE id=1;
5.update
功能:修改数据
原型:update 表名 修改语句 where 条件(无条件则全部修改)
例子:UPDATE stu SET score=60 WHERE id=1;
二.sqlite3语句
1.sqlite3_open
功能:打开数据库
原型:int sqlite3_open(
const char *filename,
sqlite3 **ppDb
);
参数:
const char *filename:打开的数据库库名
sqlite3 **ppDb:数据库操作句柄
例子:
sqlite3 * ppdb;
int sqlite3_open("./aa.db",ppdb);
2.sqlite3_close
功能:关闭数据库
原型:int sqlite3_close(sqlite3*);
例子:int sqlite3_close(ppdb);
3.sqlite3_errmsg
功能:通过出错的句柄返回错误信息
原型:const char *sqlite3_errmsg(sqlite3*);
4.sqlite3_errcode
功能:通过错误句柄返回错误码
原型:int sqlite3_errcode(sqlite3 *db)
5.sqlite3_exec
功能:执行sql语句
原型:int sqlite3_exec(
sqlite3* db,
const char *sql,
int (*callback)(void*,int,char**,char**),
void *arg,
char **errmsg
);
参数:
sqlite3* db:数据库语句操纵柄
const char *sql:要执行的sql语句
int (*callback)(void*,int,char**,char**):回调函数
void *arg:回调函数传参
char **errmsg:错误信息
1.sql语句需要char sql[128]用来存储,可以用sprintf语句编辑sql
2.由于增删改操作只需要改变数据库,所以不需要返回,用不到3,4两个参数,可以为NULL
3.查(select)操作,需要数据库返回值并输出,就需要回调函数处理返回值并输出
4.int (*callback)(void*,int,char**,char**):回调函数四个参数
void*是exec函数和callbcak函数之间的传参
int是create查到的数据个数
第一个char**是数据表的内容,是一个指针指向字符串,可以使用指针偏移实现查看下一个数据
第二个char**是数据表的列名称,也可以使用指针偏移实现查看下一个列名称