objective-c nsarray to c array

时间:2010-06-22 07:57:20

标签: c cocoa nsarray

对不起,我甚至不确定怎么问,因为我是C的完全新手,指针等等。有一个接受参数的函数:char **arg。如果我这样写这个论点:

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

并将其传递给函数:

function(cargs);

它有效。但是......我有一个NSArray NSStrings我需要使用NSArray中的值来创建此数组。我认为应该创建一个与NSArray具有相同元素数量的C数组并复制字符串,并使用cStringUsingEncoding进行转换。但老实说,我不知道怎么做,因为我对所有这些指针都很困惑。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:5)

嗯,粗略的步骤可以是:

  1. 使用NSArray的 count 方法知道NSArray中有多少个NSStrings。

  2. 使用malloc为cargs分配内存,就像这样

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

    根据你的例子,你可能还需要一个空间用于NULL,它将在cargs的末尾。

  3. 使用NSArray的循环和 objectAtIndex:来获取NSStrings,如 NSString * nsstring = [array objectAtIndex:index];

  4. 使用方法 cStringUsingEncoding:获取c-string,更好地制作副本

  5. 将这些c-string指针放入cargs

  6. 将cargs传递给你的函数,清理并释放所需的东西。

  7. 这是很多工作。 '因为混合了c和obj-c的东西。还有很多手动的malloc和免费,凌乱的东西。你不能避免它吗?

    - 添加示例代码 -

    我不太清楚你的真实意图是什么。希望这会有所帮助。

    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 :(得分:0)

@yehnan你的回答是 GREAT - 特别是因为我认为 const ** cStyle[arrays]无法动态创建...(我真的希望有一些地方只有关于C指针,变量和废话的基本信息......我发现最基本的“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;
}