2012-07-20 77 views
0

我正在尋找一個示例代碼或者如何改進下面的代碼(這是非常慢的IMO,但它是我可以寫)以最快的方式: 將2D陣列轉換爲char*並將char複製到它。將2D數組轉換爲char *數組並將字符串複製到字符串尾部的最快方法

char* 
join(int c, size_t arrsize, const char* arr[]) 
{ 
    char *buf, *tbuf, *val; 
    size_t i, vsize, total; 

    buf = malloc(1); 
    for(i = total = 0; i < arrsize; ++i) { 
    val = arr[i]; 
    vsize = strlen(val); 

    if((tbuf = realloc(buf, total + vsize + 2)) == NULL) { 
     if(buf != NULL) 
     free(buf); 
     return NULL; 
    } 

    buf = tbuf; 

    memcpy(buf + total, val, vsize); 
    total += vsize; 

    buf[total] = c; 
    total += 1; 
    } 

    buf[total] = '\0'; 
    return buf; 
} 

調用

const char *foo[] = { "a", "b", "c"}; 
char *baa = join(' ', 2, foo); //a b c 
if(baa) { 
    printf("%s\n", baa); 
    free(baa); 
} else { 
    printf("No memory\n"); 
} 

任何幫助,對優化建議非常讚賞。提前致謝。

+0

你的標題指出要追加的char的端P該字符串,但在你的代碼中,你將char放在每個字符串之間。你想要達到什麼目標? – 2012-07-20 20:07:56

回答

0

而不是重複調用realloc,你可以做一個跨越arr的第一個循環來確定總長度然後調用malloc只是一次。之後,它只是再次通過arr循環並用正確的偏移量撥打電話memcpy

像這樣的東西也許(注意,這是未經測試可能包含錯誤):

/* join strings in arr with c as separator */ 
char* join(int c, size_t arrsize, const char* arr[]) { 
    char *buf; 
    size_t i, len, total = 0; 

    /* determine total length of all strings */ 
    for (i = 0; i < arrsize; ++i) { 
    total += strlen(arr[i]); 
    } 

    /* allocate mem */ 
    buf = malloc(total + arrsize); 
    if (!buf) return NULL; 

    /* copy in all strings from arr */ 
    total = 0; 
    for (i = 0; i < arrsize; ++i) { 
    len = strlen(arr[i]); 
    memcpy(buf + total, arr[i], len); 
    total += len; 

    /* append separator (or NUL if last string) */ 
    buf[total++] = (i == arrsize-1) ? '\0' : c; 
    } 

    return buf; 
} 
+0

請注意,您並未爲每個字符串的'\ 0'保留空間。 'total + = strlen(arr [i]);'必須是'total + = strlen(arr [i])+ 1;'和'buf = malloc(total + i + 1);''其中'i'是每個'c'的空間將被存儲。另外:'c'必須被添加到最後一個循環,到'arr [i]'結尾。 – Kakashi 2012-07-20 17:30:51

+0

代碼編輯。我假設OP試圖加入char作爲分隔符的字符串,所以不,在每個字符串之後不應該有'\ 0'。除了最後一個字符串之外,我在每個字符串之後都附加了' – 2012-07-20 20:05:30

0

如果你能綁定的字符串的ARR總規模(例如,2048)。有了這個,你可以刪除重複的開銷中的strcpy和strlen的功能:

char* 
join(int c, size_t arrsize, const char* arr[]) 
{ 
    char *buffer; 
    size_t i, vsize; 
    char *b; 

    buffer = malloc(2048); 
    b = buffer; 
    vsize = 0; 
    for(i = 0; i < arrsize; ++i) { 
    char *p = arr[i]; 
    while (*p) { 
     *b = *p; 
     b++; p++; 
     vsize++; 
    } 
    *b = c; b++; 
    } 

    buffer[vsize++] = '\0'; 
    return realloc(buffer, vsize); 
} 
0
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char* join(char c, size_t arrsize, const char* arr[]){ 
    size_t i, total, len[arrsize]; 
    char *buff, *ret; 

    for(total=i=0;i<arrsize;++i) 
     total+=(len[i]=strlen(arr[i])); 
    if(NULL==(ret=buff=(char*)malloc((total + arrsize)*sizeof(char)))) 
     return NULL; 
    for(i=0;i<arrsize;++i){ 
     memcpy(buff, arr[i], len[i]); 
     buff+=len[i]; 
     *buff++=c; 
    } 
    *--buff='\0'; 
    return ret; 
} 

int main(){ 
    const char *foo[] = { "a", "b", "c"}; 
    char *baa = join(' ', sizeof(foo)/sizeof(char*), foo); //a b c 
    if(baa) { 
     printf("\"%s\"\n", baa); 
     free(baa); 
    } else { 
     printf("No memory\n"); 
    } 
    return 0; 
} 
1

我與肖恩同意,一個單一的malloc調用可能是更有利的。我對你的代碼寫了我自己拿,而他發佈了他的答案:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char* join(char delimiter, size_t arrsize, const char* arr[]) { 
    size_t i; 
    size_t total; 
    char* joined; 

    for (i = total = 0; i < arrsize; i++) { 
     if (arr[i] != NULL) 
      total += strlen(arr[i]) + 1; // size of c-style string + delimiter 
    } 

    // Note that last delimiter will actually be null termination 
    joined = (char*)malloc(sizeof(char) * total); 

    if (joined != NULL) { 
      // first character isn't guaranteed to be null termination 
      // set it so strcat works as intended, just in case 
      joined[0] = '\0'; 
     for (i = 0; i < arrsize; i++) { 
      if (arr[i] != NULL) { 
       strcat(joined, arr[i]); 

       if ((i + 1) != arrsize) 
        strncat(joined, &delimiter, 1); 
     } 
    } 

    return joined; 
} 

int main(int argc, char** argv) { 
    const char* foo[] = { "aasdasd", "bgsfsdf", "asdasisc" }; 

    char* baa = join(' ', 3, foo); 

    if (baa != NULL) { 
     printf("%s\n", baa); 
     free(baa); 
    } else { 
     printf("No memory\n"); 
    } 

    return 0; 
} 

我做這取決於我還以爲你要完成的一些變化,加入的第一個參數是用於字符分隔符單獨的組合字符串,第二個是arr中的字符串數量,第三個顯然是數組。

代碼應編譯並運行,yeilding「assdasd bgsfsdf asdasisc」,也就是我搗碎我的鍵盤上填充陣列測試時:

+0

你是C++的人嗎? :P – Kakashi 2012-07-20 17:26:36

+0

用gcc編譯,-std = c99 -pedantic -Wall。我不得不從另一個屏幕轉錄它,因爲我很懶:P – AlcoJaguar 2012-07-20 19:02:49

相關問題