用于存储sqlite db的C代码不会将数据存储在物理内存中

时间:2011-09-13 04:06:53

标签: c sqlite

虽然这个程序在我的dev-C ++编译器执行期间工作得很好,但是接收值并再次显示它,下次执行时它不会打开以前的数据库而我必须再次输入数据.db数据输入不是物理存储在内存中。请帮忙!

void fill(sqlite3* db, char* tbname);
void CreateDatabase(sqlite3** db);
void CreateTable(sqlite3* db, char* tbname);
void display(sqlite3* db, char* tbname);

int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
    int i;
    for(i=0; i<argc; i++){
        printf("%s = ",azColName[i]);
        if( argv[i] )
            printf(argv[i]);
        else
            printf("NULL");
        printf("\n");
    }

    return 0;
}

void dsperr(char**db_err)
{
    if( *db_err )
    {
        printf("db_err\n");
        sqlite3_free(*db_err); // release (free) memory
        *db_err = 0; // reinitialize the caller's pointer
    }
}

void GetTablename(char* tbname)
{
    printf("Enter the table name\n");
    scanf("%s", tbname);
}

int main()
{
    while(1)
    {
        sqlite3* db = 0; // database connection
        char tbname[DBNAMESIZE];   // table name
        int done = 0;
        while(!done)
        {
            char answer[8] = {0};
            printf("\n\nPlease select one of the folowing options\n");
            printf("1. Create a new or open an existing database\n");
            printf("2. Create a new table\n");
            printf("3. Add some data\n");
            printf("4. List all data\n");
            printf("5. Quit\n");
            scanf("%1s",answer);

            switch(answer[0])
            {
            case '1':
                CreateDatabase(&db);
                break;
            case '2':
                CreateTable(db, tbname);
                break;
            case '3':
                fill(db, tbname);
                break;
            case '4':
                display(db, tbname);
                break;
            case '5':
                done = 1;
                break;
            }
        }

    sqlite3_close(db);
    }
}

void CreateDatabase(sqlite3** db)
{
    char dbname[DBNAMESIZE];
    int n;
    printf("Please enter the name of the database\n");
    scanf("%s",dbname);
    fgets(dbname,sizeof(dbname), stdin);

    if( dbname[strlen(dbname)-1] == '\n')
        dbname[strlen(dbname)-1] = '\0';
    n = sqlite3_open(dbname, db);
    if( n != SQLITE_OK )
    {
        printf("Error opening database.\n");
    }
    else
        printf("Database open ok\n");
}

void CreateTable(sqlite3* db, char* tbname)
{
    char* db_err = 0;
    int n = 0;
    char statement[255] = {0};
    GetTablename(tbname);

    if( tbname[0] == '\0' )
        return;
    sprintf(statement, "CREATE TABLE %s (id integer);", tbname);

    n = sqlite3_exec(db, statement, NULL, 0, &db_err);
    dsperr(&db_err);
    if( n != SQLITE_OK )
    {
        printf("Error executing \"%s\"\n",statement);
    }
    else
        printf("Table created successfully\n");
}

void fill(sqlite3* db, char* tbname)
{
    char* db_err = 0;
    int id;
    int n = 0;
    char buf[80];

    if( strlen(tbname) == 0)
    {
        GetTablename(tbname);
        if( tbname[0] == '\0')
            return;
    }

    printf("Enter the data into the table\n");
    scanf("%d",&id);
    sprintf(buf,"insert into %s values(%d);", tbname, id);
    n = sqlite3_exec(db, buf, NULL, 0, &db_err);
    dsperr(&db_err);

    if( n != SQLITE_OK )
    {
        printf("Error inserting value %d\n", id);
        return;
    }
}

void display(sqlite3* db, char* tbname)
{
    char* db_err = 0;
    char select[255] = {0};
    if( strlen(tbname) == 0)
    {
        GetTablename(tbname);
        if( tbname[0] == '\0' )
            return;
    }

    if( strlen(tbname) > 0)
    {
        sprintf(select, "select * from %s;", tbname);
        sqlite3_exec(db, select, callback, 0, &db_err);
        dsperr(&db_err);
    }
}

3 个答案:

答案 0 :(得分:0)

我在几年内没有使用过C,但根据this page上的sqlite3_open()文档:

  

如果文件名是空字符串,则将创建一个私有的临时磁盘数据库。一旦数据库连接关闭,该私有数据库将自动删除。

可能你将空字符串传递给sqlite3_open()?看起来您正在阅读dbname两次,一次使用scanf,一次使用fgets

答案 1 :(得分:0)

据我所知,dbname未正确填写createdatabase。删除fgets(...)以下scanf(..)至少生成正确命名的数据库文件。

答案 2 :(得分:0)

我不确定你为什么使用

fgets(dbname,sizeof(dbname), stdin);

但它会清除dbname字符串,并创建一个临时数据库。 如果你删除这一行,它将按原样创建数据库。

此外,main中的外部while循环不是必需的,并且不允许用户退出。