2011-10-27 60 views
1

我在C中創建了一個函數,它連接了可變數量的字符串。 這是我的代碼:我使用連接帶有數字參數的函數中的數字

char* texto(const char* s, ...){ 
     va_list args; 
     char *tmp; 
     char *res; 
     size_t len = strlen(s); 

     // pega um handle ao início da lista de parâmetros 
     va_start(args, s); 
     // calcula o tamanho total de todas as strings - pega o próximo parâmetro da lista, até chegar no NULL 
     while ((tmp = va_arg(args, char*))){ 
      len += strlen(tmp); 
     } 
     va_end(args); 

     res = malloc(len+1); 
     if (!res){ 
       fprintf(stderr, "Erro ao alocar string. Função 'texto'\n"); 
       exit(EXIT_FAILURE); 
     } 

     // cria a string concatenada 
     strcpy(res, s); 

     va_start(args, s); 
     // pega o próximo parâmetro da lista, até chegar no NULL 
     while ((tmp = va_arg(args, char*))){ 
      strcat(res, tmp); 
     } 
     va_end(args); 

     return res; 
} 

這樣的:

char* txt = texto("a", "b", "c", "d", "e", NULL); 
//txt is now: "abcde" 

它工作正常。 但我不能將數字參數傳遞給這個函數,只能是字符串。 我需要改變功能,像這樣的工作:

char* txt = texto("a", "b", 1, "d", 4.5, "e", NULL); 
//txt is now: "ab1d4.5e" 

我怎麼能這樣做? 如何使用va_arg()獲取不同類型的參數?

我發現到現在的解決方案是創建一個函數int2str():

inline char* int2str(int inteiro){ 
    char* str = malloc(10); 
    sprintf(str, "%d", inteiro); 
    return str; 
} 

但我必須用這種方式:

char* txtnum = int2str(23); 
char* txt = texto("a", txtnum, NULL); 
free(txtnum); 

否則,我得到了內存泄漏...

我可以在函數texto()中使用函數int2str(),但我不知道如何檢查參數的類型!

Ps .:我使用C,而不是C++代碼。

+1

」Ps:我使用C,而不是C++代碼。「 請注意,'inline'是一個C++關鍵字,而不是C關鍵字。 – Constantinius

+0

gcc特定的解決方案是可以接受的嗎? – Flexo

+0

@Constantinius - 我認爲C99也增加了'inline'? – Flexo

回答

0

如果你願意,你可以改變int2str gcc的一個具體的解決方案是這個宏:

# define int2str(i)               \ 
    (__extension__                \ 
    ({                  \ 
     char *new = (char *) __builtin_alloca (10);      \ 
     sprintf(new, "%d", i); \ 
     new;         \ 
    })) 

這就意味着你可以寫:

char* txt = texto("a", int2str(23), NULL); 

無泄漏。它的雖然不便攜。 「

+0

謝謝@awoodland!用這段代碼我可以保持我的實際代碼沒有問題! 我會尋找這個「__extension__」來知道它是如何工作的,所以也許我可以找到一個通用的解決方案。 Tnks大家的幫助! – vinigarcia87

0

我該怎麼做?我如何使用va_arg()獲取不同類型的參數?

不幸的是,這是不可能的,當您使用可變參數列表時,類型信息會丟失。

一個很簡單的解決方案是使用聲明「類型」的格式字符串,但是接下來,爲什麼不簡單地使用標準函數snprintfReference here

char buffer[256]; 
snprintf(buffer, sizeof(buffer), "%s%s%d%s%f%s", "a", "b", 1, "d", 4.5, "e", NULL); 
+0

感謝@Constantinius,snprintf會解決我的問題。 但我正在尋找一個可以稍後使用的解決方案,該函數返回一個字符串。就像那樣。 所以我不需要擔心使用額外的變量或免費()... – vinigarcia87