c++ - 将 const unsigned char* 数据分配到数组中的正确方法是什么

标签 c++ arrays sqlite

我有以下代码:

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::mapstd::vectorstd::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::vectorC++11 功能,所以这个答案是不是你要找的东西(尽管它可能对你仍然有用)。不过,我会把它留给可能用谷歌搜索这个问题的其他人。

关于c++ - 将 const unsigned char* 数据分配到数组中的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27682625/

相关文章:

javascript - 从三个数组创建对象

c++ - 在 boolean 数组中输入

java - "java.lang.ArrayIndexOutOfBoundsException"数组逻辑问题

c++ - 我有 sqlite3 的问题

iphone - iOS 中的 SQLite 插入错误

c++ - openGL: glGenVertexArrays 访问冲突执行位置 0x00000000

c++ - 如何使用下标访问作为函数指针返回的数组?

c++ - QTreeWidget::currentItem 没有选择时返回什么?

c++ - CMake 不检测 CXX 但检测 CPP 文件

android - 屏幕旋转导致顺序调用 SQLite 出现问题