在保存到sqlite数据库之前(和之后)比较NSStrings

时间:2010-11-17 17:41:09

标签: iphone objective-c sqlite sdk nsstring

在我的Mac和iPhone上,使用objective-c,我可以将EURO字符保存到sqlite数据库。

在我存储它之前,NSString的长度是1(或者应该是2?)

从数据库中检索后,NSString的长度现在是2(或者应该是1?)

如何比较这2个NSStrings? isEqualToString不起作用。

(只要我坚持0-127字符,读/写/比较就可以正常工作。)

这是sqlite READ代码的大量修剪样本:

NSMutableString *s = [[[NSMutableString alloc] init] autorelease];
sqlite3_stmt *statement;
int i, numberOfColumns=0, columnType, numberOfRecords=0;
int anyInt;
double anyDouble;

char *anyText;

int prepareErrorNumber = sqlite3_prepare_v2(g_Db, [sqlCmd UTF8String], -1, &statement, nil);

if(prepareErrorNumber == SQLITE_OK)
{
    while(sqlite3_step(statement) == SQLITE_ROW)
    {
        numberOfRecords++;
        numberOfColumns = sqlite3_column_count(statement);

        columnType = sqlite3_column_type(statement, i);
            if(columnType == SQLITE_INTEGER) { anyInt    = sqlite3_column_int(statement, i);          [s appendFormat:@"%d", anyInt   ]; }
            if(columnType == SQLITE_TEXT   ) { anyText   = (char *)sqlite3_column_text(statement, i); [s appendFormat:@"%s", anyText  ]; }
            if(columnType == SQLITE_FLOAT  ) { anyDouble = sqlite3_column_double(statement, i);       [s appendFormat:@"%f", anyDouble]; }
        }

 ... etc...

3 个答案:

答案 0 :(得分:0)

看起来你正在尝试将insert添加为NSString并读取为UTF8String。

在编写时使用实例方法UTF8String,在阅读时使用类方法stringFromUTF8String:

答案 1 :(得分:0)

最有可能的是,您正在使用从读取中收集的信息以错误的方式创建NSString。以下是将欧元符号写入数据库然后将其读回的完整示例:

//clang -g so_sqlite3_nsstring.m -framework Foundation -lsqlite3 \
//    -o so_sqlite3_nsstring
#import <Foundation/Foundation.h>
#import <sqlite3.h>

#define DB_PATH "so_enc.db"

enum {
  ALL_OK,
  CANT_OPEN,
  CANT_CREATE,
  CANT_INSERT,
  CANT_FIND,
};

struct ExecCBCtx {
  NSString **out_string;
};
int ExecCB(void *ctx, int col_count, char *col_text[], char *col_name[]);

sqlite3 *DBCreate(void);
void DBWrite(sqlite3 *db, NSString *text);
NSString *DBRead(sqlite3 *db);

int
main(void) {
  id pool = [[NSAutoreleasePool alloc] init];
  sqlite3 *db = DBCreate();

  // Use universal character name for U+20AC "EURO SIGN".
  NSString *text = @"\u20AC";
  DBWrite(db, text);

  NSString *text2 = DBRead(db);
  (void)sqlite3_close(db);

  BOOL eq = [text isEqualToString:text2];
  NSLog(@"%@ = %@? %s", text, text2, eq? "YES" : "NO");
  [pool drain];
  return ALL_OK;
}

void
DBOpen(sqlite3 **out_db)
{
  sqlite3 *db = NULL;
  int rc = sqlite3_open(DB_PATH, out_db);
  if (rc) {
    fprintf(stderr, "sqlite3_open: %s\n", sqlite3_errmsg(*out_db));
    (void)sqlite3_close(*out_db);
    exit(CANT_OPEN);
  }
}

sqlite3 *
DBCreate(void)
{
  sqlite3 *db = NULL;
  DBOpen(&db);

  static const char CREATE_TABLE[] =
      "CREATE TABLE IF NOT EXISTS \"TEST\" (\"STRING\" char(9))";
  char *errmsg = NULL;
  int rc = sqlite3_exec(db, CREATE_TABLE, ExecCB, NULL, &errmsg);
  if (rc) {
    fprintf(stderr, "%s: %s\n", __func__, errmsg);
    sqlite3_free(errmsg);
    (void)sqlite3_close(db);
    exit(CANT_CREATE);
  }
  return db;
}

void
DBWrite(sqlite3 *db, NSString *text)
{
  static NSString *const WRITE_TABLE_FMT =
      @"INSERT INTO \"TEST\" VALUES (\"%@\")";
  NSString *writeText = [NSString stringWithFormat:WRITE_TABLE_FMT, text];
  const char *cmd = [writeText UTF8String];

  char *errmsg = NULL;
  int rc = sqlite3_exec(db, cmd, ExecCB, NULL, &errmsg);
  if (rc) {
    fprintf(stderr, "%s: %s\n", __func__, errmsg);
    sqlite3_free(errmsg);
    (void)sqlite3_close(db);
    exit(CANT_INSERT);
  }
}

NSString *
DBRead(sqlite3 *db)
{
  static const char READ_TABLE[] =
      "SELECT * FROM \"TEST\"";

  NSString *text = nil;
  struct ExecCBCtx ctx = {&text};

  char *errmsg = NULL;
  int rc = sqlite3_exec(db, READ_TABLE, ExecCB, &ctx, &errmsg);
  if (rc && rc != SQLITE_ABORT) {
    fprintf(stderr, "%s: %s\n", __func__, errmsg);
    sqlite3_free(errmsg);
    (void)sqlite3_close(db);
    exit(CANT_FIND);
  }
  sqlite3_free(errmsg);
  return text;
}

int
ExecCB(void *ctx, int col_count, char *col_text[], char *col_name[])
{
  //fprintf(stderr, "%s: %p - %d cols - %s - %s\n",
  //        __func__, ctx, col_count, col_text[0], col_name[0]);
  if (!ctx) return 0;

  struct ExecCBCtx *out = ctx;
  NSString **text = out->out_string;
  if (*text) return 1;

  *text = [NSString stringWithUTF8String:col_text[0]];
  return 0;
}

以下是样本运行的输出:

2010-11-17 14:34:05.436 so_sqlite3_nsstring[23536:903] € = €? YES

答案 2 :(得分:0)

  

=&GT;编写

时使用实例方法UTF8String

完成。 (我没有显示该代码,但它已经完成了。)

  

=&GT;和类方法stringFromUTF8String:在阅读时。

我认为这是我需要解决的问题 但它会是什么样子? 无论我如何重写它,我都无法使stringFromUTF8String工作。

if(columnType == SQLITE_TEXT   ) 
{ 
    anyText = (char *)sqlite3_column_text(statement, i); 
   [s appendFormat:@"%s", anyText]; 
}