Сравнение строк NSS до (и после) сохранения в базе данных sqlite - PullRequest
0 голосов
/ 17 ноября 2010

На моем Mac и iPhone, используя target-c, я могу сохранить символ EURO в базе данных sqlite.

Прежде чем сохранить его, длина строки NSString равна 1 (Или это должно быть 2?)

После того, как я вернул его из базы данных, длина NSString теперь равна 2 (или это должно быть 1?)

Как сравнить эти 2 строки NSString?isEqualToString не работает.

(Чтение / запись / сравнение работает нормально, пока я придерживаюсь символов 0-127.)

Это сильно урезанный пример кода READ sqlite:

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 голосов
/ 17 ноября 2010

Скорее всего, вы создаете 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
0 голосов
/ 18 ноября 2010

=> Использовать метод экземпляра UTF8String при записи

Готово.(Я не показывал этот код, но это уже было сделано.)

=> и метод класса stringFromUTF8String: при чтении.строка, которую мне нужно исправить.
Но как бы это выглядело?
Я не могу заставить работать stringFromUTF8String, как бы я ее не переписывал.

0 голосов
/ 17 ноября 2010

Похоже, вы пытаетесь добавить вставку как строку NSS и читать как строку UTF8.

Используйте метод экземпляра UTF8String при записи и метод класса stringFromUTF8String: при чтении.

...