2013-04-29 41 views
0

我想連接字符串使用stdarg()標題,但我做錯了什麼。 有一種更簡單的方法來使用realloc連接字符串?使用stdarg realloc

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdarg.h> 
void concatenaCodigo(char *string, char *format, ...){ 
    va_list args; 
    va_start(args, format); 
    int n = vsnprintf(NULL, 0, format, args); 
    string = (char*) realloc (string, n); 
    if (string != NULL) { 
     printf("Realloc OK!\n"); 
     vsprintf(string, format, args); 
     va_end(args); 
    } 
    else { 
     free (string); 
     puts ("Error (re)allocating memory"); 
     exit (1); 
    } 

} 
int main(){ 
    char *codigoC = NULL; 
    concatenaCodigo(codigoC, "Test%s%s","asd","asd"); 
    printf("%s\n", codigoC); 
} 

我做了更改。代碼應該如下所示?級聯尚未運行。

char* concatenaCodigo(char *format, ...){ 
    va_list args; 
    va_start(args, format); 
    int n = vsnprintf(NULL, 0, format, args); 
    char * newString; 
    newString = (char*) malloc(n); 
    vsprintf(newString, format, args); 
    va_end(args); 
    return newString; 
} 
int main(){ 
    char *codigoC = NULL; 
    codigoC = concatenaCodigo("Test%s%s", "asd", "asd"); 
    printf("%s\n", codigoC); 
} 
+0

您正在重新分配內存,然後將其扔掉。你需要以某種方式從函數中返回新的指針。 – 2013-04-29 03:23:04

+0

stdarg不是圖書館,它是clib的一部分,它的大部分如果不是全部只是宏 – stdcall 2013-04-29 04:55:12

回答

0

爲了避免丟失引用,我改變了接收指向char數組的指針的函數。

void concatenaCodigo(char **message, char *format, ...) 
{ 
    va_list args; 
    va_start(args, format); 
    int n = vsnprintf(NULL, 0, format, args) + 1; /* Note the +1! */ 
    va_end(args);         /* vsnprintf() 'uses up' args */ 
    char *newString = (char *) malloc(n); 
    if (newString != 0) 
    { 
     va_start(args, format);      /* Restart args */ 
     vsprintf(newString, format, args); 
     va_end(args); 
    } 
    *message = newString; 
} 
+0

根據您的估計,將雙指針傳遞給函數的好處不是簡單地從函數返回指針?它將功能與呼叫者更緊密地結合在一起。 – 2013-05-31 09:56:29

0

指針不按引用傳遞,所以,當你這樣做:

void concatenaCodigo(char *string, char *format, ...){ 
    // ... 
    string = (char*) realloc (string, n); 
} 

你覆蓋已傳遞的指針,永遠不會獲得新值該功能的。

concatenaCodigo應該返回新分配的字符串:

char* concatenaCodigo(char *format, ...) { 
    // ... 
    return string; 
} 

int main() { 
    char *codigoC = concatenaCodigo("Test%s%s","asd","asd"); 
    printf("%s\n", codigoC); 
} 

此外,你應該呼叫free(string)如果realloc失敗。您不應將NULL指針傳遞給free()

+0

請不要在註釋中張貼代碼;這是完全不可讀的。相反,[編輯原始文章](http://stackoverflow.com/posts/16270728/edit)並添加它。 – 2013-04-29 04:00:43

+0

對不起,我意識到。我將編輯原始帖子。 – 2013-04-29 04:03:00

+2

這不是調用realloc()的正確方法。如果你使用realloc(),你應該使用臨時的ptr來存儲結果。如果你不這樣做,並且realloc()失敗,那麼你就會銷燬原始文件。 – 2013-04-29 04:14:04

3

修改後的代碼中的問題是,您沒有正確重置va_list。您有:

char* concatenaCodigo(char *format, ...){ 
    va_list args; 
    va_start(args, format); 
    int n = vsnprintf(NULL, 0, format, args); 
    char * newString; 
    newString = (char*) malloc(n); 
    vsprintf(newString, format, args); 
    va_end(args); 
    return newString; 
} 
int main(){ 
    char *codigoC = NULL; 
    codigoC = concatenaCodigo("Test%s%s", "asd", "asd"); 
    printf("%s\n", codigoC); 
} 

您需要:

char *concatenaCodigo(char *format, ...) 
{ 
    va_list args; 
    va_start(args, format); 
    int n = vsnprintf(NULL, 0, format, args) + 1; /* Note the +1! */ 
    va_end(args);         /* vsnprintf() 'uses up' args */ 
    char *newString = (char *) malloc(n); 
    if (newString != 0) 
    { 
     va_start(args, format);      /* Restart args */ 
     vsprintf(newString, format, args); 
     va_end(args); 
    } 
    return newString; 
} 

int main(void) 
{ 
    char *codigoC = concatenaCodigo("Test%s%s", "asd", "asd"); 
    if (codigoC != 0) 
     printf("%s\n", codigoC); 
    free(codigoC); 
    return 0; 
} 

注意<stdarg.h>是標題,不是圖書館。

+0

謝謝@Jonathan,它工作完美。我對C沒有太多經驗,需要數天的時間才能解決問題。 – 2013-04-29 17:43:21