2013-06-28 2 views
1

Я переписываю небольшую библиотеку java для использования в объектном приложении c, которое я пишу.Проверка длины массива символов в объекте C

char[] chars = sentence.toCharArray(); 
int i = 0; 
while (i < chars.length) { ... } 

Где предложение является NSString. Я хотел бы перевести приведенный выше код Java в цель c. Вот что у меня есть до сих пор:

sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // trims sentence off white space  
const char *chars = [sentence UTF8String]; 

Как я выше, когда условие? Я не уверен, как я должен проверять длину строки после ее преобразования в массив символов.

+0

Длина строки из 'полукокса * chars' ('strlen (chars)') совпадает с длиной 'NSString * sentence' (' sentence.length'), нет? – Mario

+0

Я так считаю, но то, что я хотел, было способом получить длину от самого символа, в основном для будущей ссылки. Функция strlen была тем, что я ищу. – Malfunction

+0

В этом случае он не должен использовать -UTF8String. –

ответ

6

Ваших Objective-C строка уже имеет меру его длины, это просто вопрос вызова:

sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // trims sentence off white space  
NSUInteger length= sentence.length; 
const char *chars = [sentence UTF8String]; 

Но я хотел бы, чтобы помнить, что даже если вы не знаете длину, вы можете использовать C STRLEN функция:

sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // trims sentence off white space  
const char *chars = [sentence UTF8String]; 
size_t length= strlen(chars); 
+0

Функция strlen - именно то, что я искал. Благодаря! – Malfunction

+0

Это работает только для символов ASCII. Использование UTF8 для ASCII является неправильным. –

+0

Ну, я вижу, что он использует символы также на Java, и я думаю, что вряд ли он использует строки без * ASCII *. –

-1
int lenght = sizeof(chars)/sizeof(char) 

может работать, но он будет (инта лучшего случая) возвращает то же самый, как sentence.lenght в худшем случае 0, потому что весь указатель/SizeOf вещь я не помню

+1

Мне очень жаль, но я ничего не понимаю о том, что вы сказали. – Malfunction

+1

Это не работает, потому что * chars * - это указатель, а не массив символов. Однако * sizeof (char) * всегда возвращает 1. –

+0

@ Неисправность Это обычно используемый способ вычисления размера массива. Но это не поможет в вашем случае. –

4

Даже уже принятый ответ Я хочу предупредить об использовании 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++); 
+0

Как уже указывалось, я планирую использовать только символы ASCII. Тем не менее, объяснение, которое вы предоставили, было замечательным. Благодаря! – Malfunction