SQLite sqlite3_column_text返回损坏的数据

时间:2012-11-13 01:34:11

标签: sqlite mfc sqldatatypes c-strings corrupt

我已经尝试过strcpy,memcpy等..但遗憾的是,在最终确定sqlite后,char数据仍然存在损坏。但CString数据没有任何反应。我知道我必须在最终确定之前将该字段复制到另一个字段但不起作用。我也不确定,如果使用CString数据是安全的。

    CString StrDescription;
    char dbDescription1[110+1];

    const char *data = NULL;
    char *SQLString= new char[SQLStr.GetLength()+1] ;
    memset(SQLString,0x00,sizeof(SQLString)-1);wcstombs(SQLString,SQLStr,SQLStr.GetLength());SQLString[SQLStr.GetLength()]='\0';
    if ( sqlite3_prepare_v2( db,SQLString , -1, &stmt, NULL )!= SQLITE_OK)
    {
       sqlite3_finalize( stmt ); sqlite3_close(db); delete[] SQLString; return -1;
    }
    delete[] SQLString;

    if( sqlite3_step( stmt ) == SQLITE_ROW ) 
    {       
        data = (const char*)sqlite3_column_text( stmt, 4 ); sprintf(dbDescription1 ,"%s",data); 
        StrDescription = CString(data);
    }    

    AfxMessageBox(CString(dbDescription)); // Result is ok here..
    AfxMessageBox(StrDescription); // Result is ok here as well.

    sqlite3_finalize( stmt );  sqlite3_close(db);

    AfxMessageBox(CString(dbDescription)); // Result corrupt here
    AfxMessageBox(StrDescription); // Result still ok 


    Thanks

2 个答案:

答案 0 :(得分:0)

SQLite不检查列限制,因此可能超过110个字符。

此外,在UTF-8中,字符不一定与字节相同,因此有可能超过110个字节。

使用sqlite3_column_bytesstrlen来检查需要分配的缓冲区大小,或者只使用CString作为缓冲区。

答案 1 :(得分:0)

对我来说,这是因为StrDescription保留了字符串的副本,它在Sqlite完成清理dbDescription1指向的内存后仍然有效。因此,在这种情况下使用你的CString是安全的,并且在这种情况下比使用C语言(使用strcpy / strncpy等)制作副本更受欢迎,因为字符串类(无论是CString还是std :: string或其他)会使你免于容易犯错误。