基于SQLite3的C++支出追踪课程作业程序修改技术咨询
C++ + SQLite3 支出追踪项目实现指南
嘿,咱来一步步拆解这个课程作业的实现思路,结合你手里的导师示例程序来改,应该能很快上手~
一、先调整数据库表结构
导师给的示例表肯定缺了咱们需要的字段,首先得把表改成支持支出记录和满意度的结构。建议新增这些字段:
id:主键,自增,用来唯一标识每笔支出amount:支出金额(比如用REAL类型)category:支出类别(比如字符串,像"餐饮"、"交通")spend_date:支出日期(TEXT类型,存YYYY-MM-DD格式就行)remark:备注信息(可选,TEXT类型)satisfaction:满意度数值(比如INT类型,1-5分,1最不满意,5最满意)
给你个创建表的SQL代码,直接替换导师示例里的建表语句就行:
CREATE TABLE IF NOT EXISTS expenses ( id INTEGER PRIMARY KEY AUTOINCREMENT, amount REAL NOT NULL, category TEXT NOT NULL, spend_date TEXT NOT NULL, remark TEXT, satisfaction INTEGER CHECK(satisfaction BETWEEN 1 AND 5) );
二、核心功能实现要点
1. 支出记录的增删改
添加支出记录
写一个C++函数,接收支出的各项参数,拼接INSERT语句(或者用参数绑定更安全),调用SQLite3的API执行:
#include <sqlite3.h> #include <string> #include <cstdio> int add_expense(sqlite3* db, double amount, const std::string& category, const std::string& date, const std::string& remark, int satisfaction) { char* err_msg = nullptr; std::string sql = "INSERT INTO expenses (amount, category, spend_date, remark, satisfaction) " "VALUES (" + std::to_string(amount) + ", '" + category + "', '" + date + "', '" + remark + "', " + std::to_string(satisfaction) + ");"; int rc = sqlite3_exec(db, sql.c_str(), nullptr, 0, &err_msg); if (rc != SQLITE_OK) { printf("添加记录失败: %s\n", err_msg); sqlite3_free(err_msg); return rc; } return SQLITE_OK; }
注意:如果要避免SQL注入(比如用户输入的类别里有单引号),最好用sqlite3_prepare_v2做预处理语句,把参数绑定进去,比直接拼接字符串更安全。
修改支出记录
根据记录的id来修改指定字段,比如修改金额或者满意度:
int update_expense(sqlite3* db, int id, double new_amount, int new_satisfaction) { char* err_msg = nullptr; std::string sql = "UPDATE expenses SET amount = " + std::to_string(new_amount) + ", satisfaction = " + std::to_string(new_satisfaction) + " WHERE id = " + std::to_string(id) + ";"; int rc = sqlite3_exec(db, sql.c_str(), nullptr, 0, &err_msg); if (rc != SQLITE_OK) { printf("修改记录失败: %s\n", err_msg); sqlite3_free(err_msg); return rc; } return SQLITE_OK; }
2. 获取单笔支出的满意度
写一个查询函数,根据id找到对应的记录,返回满意度数值。这里需要用SQLite3的回调函数来处理查询结果:
#include <string> // 回调函数:把查询到的满意度存到传入的指针里 static int get_satisfaction_callback(void* data, int argc, char** argv, char** azColName) { int* satisfaction = static_cast<int*>(data); if (argc > 0 && argv[0]) { *satisfaction = std::stoi(argv[0]); } return 0; } int get_single_satisfaction(sqlite3* db, int expense_id, int& out_satisfaction) { char* err_msg = nullptr; std::string sql = "SELECT satisfaction FROM expenses WHERE id = " + std::to_string(expense_id) + ";"; int rc = sqlite3_exec(db, sql.c_str(), get_satisfaction_callback, &out_satisfaction, &err_msg); if (rc != SQLITE_OK) { printf("查询满意度失败: %s\n", err_msg); sqlite3_free(err_msg); return rc; } return SQLITE_OK; }
三、调试小技巧
- 先在SQLite3命令行工具里测试你的SQL语句,确保能正常执行后再写到C++代码里
- 每次调用SQLite3 API后都检查返回码(
SQLITE_OK是成功),打印错误信息能快速定位问题 - 如果遇到回调函数没触发,检查SQL语句是否真的查询到了数据
内容的提问来源于stack exchange,提问作者KingKenny04
相关产品推荐
相关产品推荐

