我有以下代码:
sqlite *sql = new sqlite; // create a new sqlite object.
const char *dbFile = "database.db"; // sqlite database file.
sql->open(dbFile); // open the connection.
sql->query("SELECT * FROM categories"); // make a query.
int numRows = sql->numRows(); // get the number of rows.
const unsigned char *result[numRows]; // an array to store data that will be brought in from the database.
int index = 0; // counter
while(sql->fetch() != SQLITE_DONE){
// store the data into an array
result[index] = sql->getValue("name");
index++;
// print the data directly without storing in an array
cout << sql->getValue("name") << endl;
}
sql->close();
// print the content of the `result` array.
for(int i=0;i<numRows;i++){
cout << result[i] << endl;
}
结果:
注意事项:
sql->getValue("name");
方法返回const unsigned char*
数据。
正如您在结果图像中看到的,为什么直接打印数据时没有出现问题,而打印时存储在数组中的相同数据却没有出现?
解决方案
首先:我感谢所有贡献(通过评论或回答)帮助我找到问题解决方案的人。 他们的回答确实值得最佳答案。
sqlite *sql = new sqlite;
const char *dbFile = "database.db";
sql->open(dbFile);
sql->query("SELECT * FROM categories");
int numRows = sql->numRows();
char **result = (char**)malloc(sizeof(char*) * numRows);
int index = 0;
while(sql->fetch() != SQLITE_DONE){
result[index] = (char*)malloc(sizeof(char*) * CHAR_MAX);
strcpy(result[index], reinterpret_cast<const char*> (sql->getValue("name")));
index++;
cout << sql->getValue("name") << endl;
}
cout << "\n\n" << endl;
sql->close();
for(int i=0;i<numRows;i++){
cout << *(result+i) << endl;
}
结果:
最佳答案
我最近开始自己研究 Sqlite,所以我碰巧有一些代码我已经提取出来作为示例。这不应该只是为了完成工作而特别性能。
它还包含使 SQL REGEXP
函数正常工作的代码。
想法是在 select 回调
期间将元素添加到数据结构。数据结构是 std::map
的 std::vector
。 std::map
是从列名称映射的表列数据,std::vector
包含列的行:
#include <map>
#include <regex>
#include <string>
#include <vector>
#include <iterator>
#include <iostream>
#include <sqlite3.h>
typedef std::map<std::string, std::string> result;
typedef std::vector<result> result_vec;
#define log(msg) std::cout << msg << std::endl
static int select_callback(void* user, int argc, char** argv, char** azColName)
{
result_vec& v = *static_cast<result_vec*>(user);
result r;
for(int i = 0; i < argc; ++i)
if(argv[i])
r.emplace(azColName[i], argv[i]);
v.emplace_back(std::move(r));
return 0;
}
static void regexp_callback(sqlite3_context* context, int argc,
sqlite3_value** argv)
{
unsigned count = 0;
if(argc == 2)
{
const char* pattern = (const char*) sqlite3_value_text(argv[0]);
const char* value = (const char*) sqlite3_value_text(argv[1]);
if(pattern && value)
{
std::string s = value;
std::regex r(pattern, std::regex::icase);
std::smatch m;
if(std::regex_search(s, m, r))
count = m.size();
}
}
sqlite3_result_int(context, (int) count);
}
sqlite3* open(const std::string& name)
{
sqlite3* db;
if(sqlite3_open(name.c_str(), &db) != SQLITE_OK)
{
log("ERROR: opening db: " << name);
log("ERROR: " << sqlite3_errmsg(db));
return nullptr;
}
sqlite3_create_function_v2(db, "REGEXP", 2, SQLITE_ANY, 0, regexp_callback, NULL, NULL, NULL);
return db;
}
bool select(sqlite3* db, const std::string& sql, result_vec& v)
{
char* error = 0;
if(sqlite3_exec(db, sql.c_str(), select_callback, &v, &error) != SQLITE_OK)
{
log("ERROR: " << error);
log("ERROR: " << sqlite3_errmsg(db));
log(" SQL: " << sql);
sqlite3_free(error);
return false;
}
return true;
}
int main()
{
sqlite3* db = open("mydatabase.db");
if(db)
{
result_vec results;
if(!select(db, "select * from mytable", results))
return 1;
for(auto&& row: results)
for(auto&& col: row)
std::cout << col.first << ": " << col.second << '\n';
}
}
注意:我刚读到您不想使用 std::vector
或 C++11 功能,所以这个答案是不是你要找的东西(尽管它可能对你仍然有用)。不过,我会把它留给可能用谷歌搜索这个问题的其他人。
关于c++ - 将 const unsigned char* 数据分配到数组中的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27682625/