Сломанная кодировка при получении данных из базы данных sqlite - PullRequest
0 голосов
/ 07 марта 2012

Я храню данные приложения (кириллические строки) в sqlite. Когда я пытаюсь отобразить эти данные в приложении, вместо текста появляются странные символы. Вот как я получаю данные.

-(NSString *)getData
{
    sqlite3 *database;

    if(sqlite3_open([[self dataFilePath] UTF8String], &database) != SQLITE_OK)
    {
        sqlite3_close(database);
    }

    NSString *query = [NSString 
                       stringWithFormat:@"SELECT name FROM users WHERE kind = '%@' ORDER BY RANDOM() LIMIT 1", self.kind ];
    sqlite3_stmt *statement;

    NSString *selectedQuestion;

    if(sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
    {
        sqlite3_step(statement);
        selectedQuestion =[NSString stringWithFormat: @"%s",(char *)sqlite3_column_text(statement, 0)];
        sqlite3_finalize(statement);
    }

    sqlite3_close(database);

    return selectedQuestion;
}

Ответы [ 2 ]

3 голосов
/ 08 марта 2012

Предполагая, что вы используете UTF-8, а не UTF-16 sqlite базы данных, вы, вероятно, будете счастливее использовать:

selectedQuestion = [NSString stringWithUTF8String: (char*)sqlite3_column_text(statement,0)];

И, в более общем плане:

selectedQuestion = [NSString stringWithCString: (char*) sqlite3_column_text(statement,0) encoding: ENCODING];

может использоваться для других кодировок, которые являются NUL-безопасными.Например, замените ENCODING на NSUTF16StringEncoding для UTF16 (и есть варианты для версий BE и LE, если вы знаете заранее и не можете ожидать, что маркер будет там).

Для кодировок, которые не заканчиваются NUL, вы можете использовать:

selectedQuestion = [[[NSString alloc] initWithBytes: ptr  length: length encoding: ENCODING] autorelease];

, где ptr и length имеют расположение и длину строки, а ENCODING, как указано выше, указывает на ENCODING из списка доступных кодировок.

0 голосов
/ 06 ноября 2013

Немного об этой стороне, но я решил эту проблему, сохранив данные UTF16 из строки в столбце типа BLOB-объекта sqlite3.

Вот эскиз того, что я сделал (без проверки ошибок):

1) Создать таблицу с помощью BLOB-объекта;

sqlite3_exec(database, "CREATE TABLE my_table (my_text BLOB NOT NULL);");

2) При вставке обязательно подготовьте свое заявление с помощью большого двоичного объекта:

// "text" is the NSString you want to save
sqlite3_stmt *w_statement = nil;
sqlite3_prepare_v2(database,"INSERT INTO my_table (my_text) VALUES (?);", -1, &w_statement,  NULL);
NSData *utf16Data = [text dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
sqlite3_bind_blob(w_statement, 1, [utf16Data bytes], [utf16Data length], NULL);
sqlite3_step(w_statement);

3) при чтении:

// statement is your select statement
const void *textBytes = sqlite3_column_blob(statement, 1);
NSData *textData = [NSData dataWithBytes:textBytes length:(sqlite3_column_bytes(statement, 1))];
NSString *text = [[NSString alloc] initWithData:textData encoding:NSUTF16LittleEndianStringEncoding];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...