繁体   English   中英

使用Sqlite3 C ++和VisualStudio2010在INSERT期间编码问题

[英]Encoding problems during INSERT with Sqlite3 C++ and VisualStudio2010

我正在使用sqlite3和C ++ API以及VisualStudio 2010为一个项目开发一个小包装器。就像使用SQLiteDataBaseBrowser这样的工具进行检查一样,主要问题是我尝试在表中插入的信息显示为损坏/根本没有出现。 该表似乎是使用UTF8编码正确创建的。

我尝试将VS中的字符集配置值用作“使用多字节字符集”,并尝试使用“使用Unicode字符集”,但结果没有变化。 两者都给我带来了与损坏数据相同的问题。 我使用典型的std :: strings转换为legacy c char *,正如我在几个例子中看到的,它应该与API提供的sqlite3_bind_text(...)函数一起正常工作。

    sqlite3_bind_int(stmt, 1, newShop.GetId());
    sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, newShop.GetLocation().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 4, newShop.GetPicturePath().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 5, newShop.GetRegisters().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 6, newShop.GetMixes().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 7, newShop.GetAllowedUsers().c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int(stmt, 8, newShop.IsAvailable() == true?1:0);

newShop是一个类的实例,它包含std :: strings和int中的信息。 我不得不说使用int类型的绑定,工作完美且没有问题,但其他人看起来完全搞砸了。 当字符串被硬编码时,它们看起来还不错,直到我尝试插入特殊字符,如“áàä”等。

该表是使用以下语句创建的:

char *szSQL = "CREATE TABLE IF NOT EXISTS SHOPS (ID INTEGER PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, LOCATION TEXT, PICTUREPATH TEXT, REGISTERS TEXT, MIXES TEXT, USERS TEXT, AVAILABLE INTEGER NOT NULL);";
int rc = sqlite3_exec(db, szSQL, NULL, 0, NULL);

这是我使用上面的代码片段插入数据时的外观:

DataBase编码问题

从WINUNIT测试发送它看起来像:

Shop shOne = Shop(1234, "Its about nothing", "Manhattan", "seinfeld.jpg", "1111,2222,3333", "1000x1,2000x7", "10,11,12", true); 
Shop shTwo = Shop(4321, "Louie", "Manhattan", "", "1111,5555", "50000x1,10000x5", "60,70", true);

WIN_ASSERT_EQUAL(0, auxsql.InsertShop(shOne));
WIN_ASSERT_EQUAL(0, auxsql.InsertShop(shTwo));

插入,提交,创建sql语句或对sqlite3 API的任何其他函数调用都不会返回错误代码。

我找到了解决方案。 它与编码无关,正如我想的那样,因为在DB浏览器中奇怪地表示了字符,而且与长度无关。

问题出在绑定的最后一个参数中。 在我传递SQLITE_STATIC的地方,我应该传递SQLITE_TRANSIENT,因为我想要绑定的调用返回的对象可能在执行查询之前被破坏。 正如在另一个问题中解释的那样:

sqlite3_bind_text用于c ++字符串的SQLITE_STATIC与SQLITE_TRANSIENT

我认为sqlite引用非常清楚API的用法。

在具有第四个参数的那些例程中,其值是参数中的字节数。 要清楚:值是值中的字节数,而不是字符数。

根据您的使用情况,

sqlite3_bind_text(stmt, 2, newShop.GetName().c_str(), -1, SQLITE_STATIC); 第四个论点是-1 但它应该是newShop.GetName().length或strlen(newShop.GetName()。c_str())`

注意:处理具有多宽字符的字符串时要小心。 strlen(chinese string) ! = chinese string.len strlen(chinese string) ! = chinese string.len 请参阅此处了解更多详情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM