Даже уже принятый ответ Я хочу предупредить об использовании strlen(), даже в этом случае это может быть без проблем. Существуют различия между NSString и C-Strings.
А. -length
(NSString
) и strlen()
имеет различную семантику:
NSString
не \ 0 завершающим, но на основе длины (!). Он может хранить \ 0 символов. Это очень легко получить различную длину, если есть \ 0 символ в экземпляре строки:
NSString *sentence = @"Amin\0Negm";
NSLog(@"length %ld", [sentence length]); // 9
const char *chars = [sentence cStringUsingEncoding:NSUTF8StringEncoding];
size_t length= strlen(chars);
NSLog(@"strlen %ld", (long)length); // 4
length 9
strlen 4
Но -UTF8String
и даже использовали -cStringUsingEnocding:
(оба NSString
) выписывать всю строку, хранящуюся в экземпляре строки. (Я думаю, что в случае -cStringUsingEncoding
это вводит в заблуждение, поскольку стандартные строковые функции, такие как strlen()
всегда использует первый \ 0, как прекращение строк.)
B. В UTF8 персонаж может иметь многобайтовые. Символ в C - один байт. (С байта не в значении 8 бит, но наименьший адресуемый блок.)
NSString *sentence = @"Αmin Negm";
NSLog(@"length %ld", [sentence length]);
const char *chars = [sentence UTF8String];
size_t length= strlen(chars);
NSLog(@"strlen %ld", (long)length);
length 9
strlen 10
WTF здесь произошло? «А» Амина - это не латинская прописная буква А, а греческая прописная буква Альфа. В UTF8 это занимает два байта, а для чистой строки C - два символа!
NSLog(@"%x-%x %x-%x", 'A', 'm', (unsigned char)*chars, (unsigned char)*(chars+1));
41-6d ce-91
Первые два числа являются кодами для «A», «т», вторые две цифры являются UTF8 код греческой буквы альфа (CE 91).
Я не думаю, что это хорошая идея просто перейти от NSString
к char *
без уважительной причины и полного понимания проблем. Если вы не ожидаете таких символов, используйте NSASCIIStringEncoding
. Если вы ожидаете, что такие персонажи снова и снова проверяют ваш код ... или читают C.
C. C поддерживает широкие символы. Это похоже на unichar для Mac OS, но напечатано wchar_t
. Для wchar_t в wchar.h есть строковые функции.
NSString *sentence = @"Αmin Negm";
NSLog(@"length %ld", [sentence length]);
wchar_t wchars[128]; // take care of the size
wchar_t *wchar = wchars;
for (NSUInteger index = 0; index < [sentence length]; index++)
{
*wchar++ = [sentence characterAtIndex:index];
}
*wchar = '\0';
NSLog(@"widestrlen %ld", wcslen(wchars));
length 9
widestrlen 9
D. Очевидно, вы хотите выполнить итерацию по строке. Общий шаблон в чистом C не должен использовать индекс и сравнивать его с длиной и определенно не до strlen()
в каждом цикле, потому что он приводит к высоким затратам. (Строки C не длина на основе так что вся строка должна быть отсканирована снова и снова.) Вы просто увеличиваете указатель на следующий знак:
char letter;
while ((letter = *chars++)) {…}
или
do
{
// *chars points to the actual char
} while (*char++);
Длина строки из 'полукокса * chars' ('strlen (chars)') совпадает с длиной 'NSString * sentence' (' sentence.length'), нет? – Mario
Я так считаю, но то, что я хотел, было способом получить длину от самого символа, в основном для будущей ссылки. Функция strlen была тем, что я ищу. – Malfunction
В этом случае он не должен использовать -UTF8String. –