За ответ @ метатации смещение указывается в байтах, а не в символах. Текст в вашей базе данных, вероятно, является Unicode в кодировке UTF8, и в этом случае любой не-ASCII символ представляется несколькими байтами . Примеры символов, отличных от ASCII, включают символы с акцентами (à, ö и т. Д.), Умные кавычки, символы из наборов нелатинских символов (греческий, кириллица, большинство азиатских наборов символов и т. Д.) И т. Д.
Если байты в базе данных SQLite представляют собой строки Юникода в кодировке UTF8, вы можете определить истинное смещение символов Юникода для данного байтового смещения следующим образом:
NSUInteger characterOffsetForByteOffsetInUTF8String(NSUInteger byteOffset, const char *string) {
/*
* UTF-8 represents ASCII characters in a single byte. Characters with a code
* point from U+0080 upwards are represented as multiple bytes. The first byte
* always has the two most significant bits set (i.e. 11xxxxxx). All subsequent
* bytes have the most significant bit set, the next most significant bit unset
* (i.e. 10xxxxxx).
*
* We use that here to determine character offsets. We step through the first
* `byteOffset` bytes of `string`, incrementing the character offset result
* every time we come across a byte that doesn't match 10xxxxxx, i.e. where
* (byte & 11000000) != 10000000
*
* See also: http://en.wikipedia.org/wiki/UTF-8#Description
*/
NSUInteger characterOffset = 0;
for (NSUInteger i = 0; i < byteOffset; i++) {
char c = string[i];
if ((c & 0xc0) != 0x80) {
characterOffset++;
}
}
return characterOffset;
}
Предупреждение: если вы используете смещение символа для индексации в NSString
, имейте в виду, что NSString
использует UTF-16 под капотом, поэтому отображаются символы с кодовой точкой Unicode выше, чем U + FFFF на пару из 16-битных значений. Как правило, вы не будете сталкиваться с этим для текстового содержимого, но если вы заботитесь об особо непонятных наборах символов, или о некоторых нетекстовых символах, которые Unicode может представлять, таких как Emojis, то приведенный выше алгоритм потребует улучшений, чтобы удовлетворить их.
(Фрагмент кода из моего проекта - не стесняйтесь его использовать.)