从sqlite数据库获取数据时的编码损坏

时间:2012-03-07 19:39:42

标签: objective-c ios sqlite

我将应用程序数据(西里尔字符串)存储在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 个答案:

答案 0 :(得分:3)

假设您使用的是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安全编码。例如,用UTUT16的NSUTF16StringEncoding替换ENCODING(如果你提前知道并且不能指望标记在那里,则有BE和LE版本的变体)。

对于非NUL终止的编码,您可以使用:

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

其中ptr和length具有字符串的位置和长度,ENCODING如上所示,表示可用编码列表中的ENCODING。

答案 1 :(得分:0)

关于这个派对的一点点,但我通过从sqlite3 blob类型列中的字符串保存UTF16数据来解决这个问题。

这是我所做的草图(减去错误检查):

1)使用blob创建表;

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

2)插入时,请务必使用blob准备语句:

// "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];