2010-06-22 3 views
3

Извините, я даже не знаю, как спросить, так как я полный новичок в C, указатели и тому подобное. Есть функция, которая принимает аргумент: char **arg. Если я пишу этот аргумент так:object-c nsarray to c array

char *cargs[] = {"blah", NULL}; 

и передать его функции:

function(cargs); 

это работает. но ... У меня есть NSArray из NSStrings, и мне нужно сделать этот массив вне значений от NSArray. Я решил, что нужно создать массив C из того же элемента, что и NSArray, и скопировать строки, конвертируя их с cStringUsingEncoding. Но я честно понятия не имею, как это сделать, так как я запутался со всеми этими указателями и тому подобное. Любая помощь будет оценена по достоинству.

ответ

4

Ну, грубые шаги могут быть:

  1. использование количества метод NSArray, чтобы узнать, сколько NSStrings есть в NSArray.

  2. использование таНос выделить память для cargs, что-то вроде этого

    char **cargs = (char **) malloc(sizeof(char *) * count); 
    

    по вашему примеру, вам может понадобиться более одного помещения для NULL, который будет в конце cargs.

  3. использовать цикл и objectAtIndex: из NSArray, чтобы выйти на NSStrings, как NSString * NSString = [массив objectAtIndex: индекс];

  4. метод использование cStringUsingEncoding: получить кесареву строку из, лучше сделать копию

  5. положить эти с-строковые указатели в cargs

  6. пасс cargs к вашей функции, чистой и свободной что нужно.

Это очень много работы. Потому что смесь c и obj-c. И много ручного malloc и свободного, грязного материала. Вы не можете избежать этого?

--add образец code--

Я не совсем уверен, что ваша реальная цель заключается. Надеюсь, это поможет.

void func(char **arg) 
{ 
    int i; 
    for(i = 0; arg[i] != NULL; i++) { 
     printf("%d=%s\n", i, arg[i]); 
} 
} 
int main(int argc, const char *argv[]) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSString *s1 = [NSString stringWithString:@"first"]; 
    NSString *s2 = [NSString stringWithString:@"second"]; 
    NSString *s3 = [NSString stringWithString:@"third"]; 

    NSArray *array = [NSArray arrayWithObjects: s1, s2, s3, nil]; 
    //by now, we have an NSArray of three NSStrings 

    int count = [array count]; 
    char **cargs = (char **) malloc(sizeof(char *) * (count + 1)); 
    //cargs is a pointer to 4 pointers to char 

    int i; 
    for(i = 0; i < count; i++) { 
     NSString *s = [array objectAtIndex:i];//get a NSString 
     const char *cstr = [s cStringUsingEncoding:NSUTF8StringEncoding];//get cstring 
     int len = strlen(cstr);//get its length 
     char *cstr_copy = (char *) malloc(sizeof(char) * (len + 1));//allocate memory, + 1 for ending '\0' 
     strcpy(cstr_copy, cstr);//make a copy 
     cargs[i] = cstr_copy;//put the point in cargs 
    } 
    cargs[i] = NULL; 

    func(cargs);//call the function to do something 

    for(i = 0; i < count; i++) { 
     free(cargs[i]); 
    } 
    free(cargs); 

    [pool drain]; 
    return 0; 
} 
+1

Зачем посылать' lengthOfBytesUsingEncoding: '' cStringUsingEncoding:. 'Автоматически создаст строку нужной длины, на самом деле, вы не можете сказать ему, чтобы использовать другую длину –

+0

Ну, я бы рад избежать этого, но я использую AuthorizationExecuteWithPrivileges для запуска сценария оболочки с повышенными привилегиями, и я не знаю другого способа это сделать. – Marius

+0

char * arg; \t arg = (char *) malloc ([a count ] + 1); \t \t для (INT I = 0; г <[счетчик]; я ++) { \t \t \t arg [i] = [[a get: i] cStringUsingEncoding: NSUTF8StringEncoding] [0]; \t} \t \t arg [[a count]] = 0; Это то, что я придумал с помощью моего друга, но он разбивает AuthorizationExecuteWithPrivileges ... Как мне отформатировать код в комментарии? :( – Marius

0

@yehnan ваш ответ GREAT - особенно потому, что я думал, чтоconst ** cStyle[arrays] не смогли быть созданы динамически ... (я действительно хотел было где-то только с основной информацией о C указателей и переменные и дерьмо ... Я нахожу, что самые базовые «примитивы С» гораздо более сбивают с толку, чем что-либо еще ...) Вот ваш хороший маленький пример «в комплекте» в функцию ... »для детей .. , "

char ** cArrayFromNSArray (NSArray* array){ 
    int i, count = array.count; 
    char **cargs = (char**) malloc(sizeof(char*) * (count + 1)); 
    for(i = 0; i < count; i++) {  //cargs is a pointer to 4 pointers to char 
     NSString *s  = array[i];  //get a NSString 
     const char *cstr = s.UTF8String; //get cstring 
     int   len = strlen(cstr); //get its length 
     char *cstr_copy = (char*) malloc(sizeof(char) * (len + 1));//allocate memory, + 1 for ending '\0' 
     strcpy(cstr_copy, cstr);   //make a copy 
     cargs[i] = cstr_copy;   //put the point in cargs 
    } 
    cargs[i] = NULL; 
    return cargs; 
}