Объединить текст с числами в функцию с переменным количеством параметров - PullRequest
1 голос
/ 27 октября 2011

Я сделал функцию в 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;
}

Но я должен использовать этот способ:1015 *

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

в противном случае я получил утечку памяти ...

Я мог бы использовать функцию int2str () внутри функции texto (), но я не знаю, как проверить типпараметры!

Ps .: Я использую C, а не C ++ для моего кода.

Ответы [ 2 ]

0 голосов
/ 27 октября 2011

Если вы готовы принять решение для конкретного gcc, вы можете изменить int2str на этот макрос:

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

Это означает, что вы можете написать:

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

без утечки.Это очень непереносимо.

0 голосов
/ 27 октября 2011

Как я могу это сделать? Как получить параметры с разными типами, используя va_arg ()?

К сожалению, это невозможно, информация о типах теряется при использовании списков переменных аргументов.

Одним из довольно простых решений является использование строки формата, которая объявляет «типы», но опять же, почему бы вам просто не использовать стандартную функцию snprintf? Ссылка здесь .

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