Чтобы расширить мой предыдущий комментарий:
Я не знаю, что такое TCHAR
, но ваш заголовок относится к wchar, и вы используете широкие строковые литералы, поэтому я предполагаю, что это псевдоним для wchar_t
.
Sqlite ожидает строки Unicode с API, которые принимают или возвращают строки в кодировке UTF-8 и строки в кодировке UTF-16.Если вы используете какую-то другую кодировку, вы должны преобразовать ее в одну из них перед сохранением строки в виде sqlite TEXT
(вы всегда можете сохранить ее как BLOB
, который является просто необработанным массивом байтов, если вы не используетене хочу или не могу конвертировать, но sqlite будет обрабатывать это иначе, чем строка).Внутри строки хранятся как UTF-8 по умолчанию.В новой базе данных перед созданием таблиц вы можете изменить ее на различные формы UTF-16 с прагмой encoding
.Тем не менее, он игнорируется после создания базы данных, и, поскольку по умолчанию используется UTF-8, вам не нужно включать его в пример кода.
Теперь кодировка, используемая широкими строками, является реализацией изависит от локали.Это может быть UTF-16, это может быть даже не Unicode вообще (но на моем компьютере это UTF-32).Таким образом, в переносимом коде вам придется преобразовывать широкую строку в строку UTF-8 или UTF-16, первую из которых довольно легко сделать.Более того, в C ++ есть строковые литералы UTF-16, которые можно использовать вместо широких строк.
В следующем коде показаны примеры как непосредственного использования UTF-16, так и преобразования широких строк в строки UTF-8 для вставки в базу данных.,Он также демонстрирует обычный рабочий процесс подготовки оператора, привязки к нему значений и его выполнения.
#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);
}