1

我已经尝试过 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
4

2 回答 2

1

在我看来,这是因为 StrDescription 保留了字符串的副本,在 Sqlite 完成清理 dbDescription1 指向的内存后它仍然有效。所以是的,在这种情况下使用你的 CString 是安全的,并且在这种情况下优先于以 C 方式(使用 strcpy/strncpy 等)制作副本,因为字符串类(无论是 CString 还是 std::string 或其他)将保护您免受容易犯的错误。

于 2012-11-15T15:42:55.793 回答
0

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

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

使用sqlite3_column_bytesstrlen检查您需要分配多大的缓冲区,或者仅使用 aCString作为缓冲区。

于 2012-11-13T14:46:36.163 回答