c++ - 如何使用c++在sqlite中插入wchar?

标签 c++ sqlite

我有 TCHAR 数组,我想将该数组插入到 mytable 中,我正在尝试这样:-

  int val = sqlite3_open("test.db", &db);
    if (val)
    {
        cout << "Can't open database: " << sqlite3_errmsg(db) << "\n";
    }
    else
    {
        cout << "Open database successfully\n\n";
        sqlite3_exec(db, "PRAGMA encoding =  UTF-8", NULL, NULL, NULL);
    }
    TCHAR *name = L"ひらがな";
    TCHAR query[50];
    wsprintf(query,"L"insert into myTable (Name, Age) VALUES ('%ws',25)",name);
    int rc = sqlite3_exec(db, (const char*)query, callback, 0, &zErrMsg);
    if (rc != SQLITE_OK)
        {
            cout << "SQL error: " << sqlite3_errmsg(db) << "\n";
            sqlite3_free(zErrMsg);
        }

最佳答案

扩展我之前的评论:

我不知道 TCHAR 是什么,但您的标题是关于 wchar 并且您使用宽字符串文字,因此我认为它是 wchar_t 的别名。

Sqlite 需要 Unicode 字符串,其 API 接受或返回 UTF-8 编码字符串和 UTF-16 编码字符串。如果您使用其他编码,则必须先转换为其中一种编码,然后才能将字符串存储为 sqlite TEXT 类型(您始终可以将其存储为 BLOB )如果您不想或无法转换,则只是一个原始字节数组,但 sqlite 会以不同于字符串的方式对待它)。在内部,字符串默认存储为 UTF-8。对于全新的数据库,在创建任何表之前,您可以使用 encoding pragma 将其更改为各种形式的 UTF-16。不过,一旦创建了数据库,它就会被忽略,并且由于它默认为 UTF-8,因此您实际上不需要在示例代码中包含它。

现在,宽字符串使用的编码取决于实现和区域设置。它可能是 UTF-16,甚至可能根本不是 Unicode(但在我的计算机上它是 UTF-32)。因此,在可移植代码中,您必须将宽字符串转换为 UTF-8 或 UTF-16 字符串,第一个字符串非常容易做到。更好的是,C++ 具有 UTF-16 字符串文字,您可以使用它来代替宽字符串。

以下代码显示了直接使用 UTF-16 以及将宽字符串转换为 UTF-8 字符串以插入数据库的示例。它还演示了 usual workflow准备一个语句,将值绑定(bind)到它,然后执行它。

#include <codecvt>
#include <iostream>
#include <locale>
#include <string>
#include <sqlite3.h>

int main() {
  sqlite3 *db;
  int val = sqlite3_open("test.db", &db);
  if (val) {
    std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
    return 1;
  }

  // Use a ASCII (And thus UTF-8) string
  char *errmsg;
  if (sqlite3_exec(db,
                   "CREATE TABLE IF NOT EXISTS myTable(name TEXT, age INTEGER)",
                   nullptr, nullptr, &errmsg) != SQLITE_OK) {
    std::cerr << "Sqlite error: " << errmsg << '\n';
    return 1;
  }

  sqlite3_stmt *stmt;
  // Use a  UTF-16 string literal
  val = sqlite3_prepare16_v2(db, u"INSERT INTO myTable(name,age) VALUES (?,?)",
                             -1, &stmt, nullptr);
  if (val != SQLITE_OK) {
    std::cerr << "Sqlite error: " << sqlite3_errmsg(db) << '\n';
    return 1;
  }

  // Convert a wide string to a UTF-8 string
  std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
  std::wstring name = L"ひらがな";
  auto converted = conv.to_bytes(name);
  // And bind it
  sqlite3_bind_text(stmt, 1, converted.c_str(), converted.size(),
                    SQLITE_STATIC);
  sqlite3_bind_int(stmt, 2, 25);
  val = sqlite3_step(stmt);
  if (val != SQLITE_DONE) {
    std::cerr << "Sqlite error: " << sqlite3_errmsg(db) << '\n';
    return 1;
  }
  sqlite3_finalize(stmt);
  sqlite3_close(db);
}

关于c++ - 如何使用c++在sqlite中插入wchar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52930089/

相关文章:

c++ - 有没有办法使用十进制 ASCII 码通过自动类型推断来获取字符?

c++ - 当 >> 运算符试图输入一个大于变量可以包含的值时会发生什么?

c++ - OpenCL:for 循环中的 CL_OUT_OF_RESOURCES

android - 如何为 android 应用程序加密 SQlite 数据库?

android - GreenDAO - 多列上的主键

java - 在 Java 中仅在堆上创建对象的优缺点是什么?

c++ - 从按值构造函数参数初始化的引用成员

android - 以编程方式备份​​没有root权限的android通话记录和短信

android - 在 SQLite 中存储浮点值会更改 Room DB 中的小数精度

java - 通过 Jsoup 更新效果不佳