2016-09-23 3 views
0

Ich habe ein NSArray<NSString*>* Objekt, und ich muss eine C-API aufrufen, die ein Array von Zeichenfolgen wie char** übernimmt.Wie konvertiert man ein Array von NSString in ein Array von C-Strings?

Was ist der beste Weg, dies zu tun? Die wichtige Anmerkung ist die c-strings darf keine const Modifier, so etwas wie das folgende ist nicht gut genug, da UTF8String kehrt const char*:

NSArray<NSString*>* names = ...; 
int len = args.count; 
char* cNames[len]; 
for(int i = 0; i < len; i++) { 
    cNames[i] = names[i].UTF8String; 
}; 
+0

Wird die C-API den Inhalt der Zeichenfolgen ändern? – kennytm

+0

Ich glaube nicht, aber in der Theorie könnte es. – zeroimpl

+1

Wenn dies der Fall ist, wird nichts das ursprüngliche NSArray ändern. Das obige ist im Grunde der richtige Ansatz. Sie möchten nur die langweiligen 'malloc' und' strncpy' hinzufügen, um eine vollständige Kopie zu erstellen. Die Antwort ist: das obige, plus C. –

Antwort

1

Sie werden einige dynamische Speicher tun wollen, da Sie nicht verlassen können der Sicherungsspeicher für UTF8String wird freigegeben.

NSArray *strings = @[ @"String 1", @"Other string", @"Random String"]; 
char **cStrings = NULL; 
NSInteger numCStrings = strings.count; 

if (numCStrings) { 
    cStrings = (char **)calloc(numCStrings, sizeof(char*)) ; 

    if (cStrings) { 
     // Safer to allocate memory for each string 

     for (NSInteger i=0;i<numCStrings;i++) { 
      NSString *nsString = strings[i]; 
      char *cString = (char *)malloc([nsString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1); // + 1 for \0 

      if (cString) { 
       strcpy(cString, nsString.UTF8String); 
       cStrings[i] = cString; 
      } else { 
       // You should handle your error 
      } 
     } 
    } else { 
     // You should handle your error 
    } 
} 

for (NSInteger i=0;i<numCStrings;i++) { 
    NSLog(@"C-String (%ld): %s", i, cStrings[i]); 
} 

// Note you need to free your memory later! 
// Do any additional setup after loading the view, typically from a nib. 
for (NSInteger i=0;i<numCStrings;i++) { 
    if (cStrings[i]) { 
     // Free each string 
     free(cStrings[i]); 
    } 
} 

// Free the array 
free(cStrings); 

cStrings = NULL; 
numCStrings = 0; 
+0

Danke. Hässlich, aber ich denke, es wird reichen! – zeroimpl

+0

Eine kleine Korrektur - 'nsString.length' gibt die Länge in der UTF-16-Codierung zurück. Sie müssen '[nsString lengthOfBytesUsingEncoding: NSUTF8StringEncoding]' verwenden – zeroimpl

Verwandte Themen