在参数数量可变的函数中将文本与数字连接起来

发布于 2024-12-12 03:18:26 字数 1695 浏览 1 评论 0原文

我用 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++。

I made a function in C, that concatenates a variable number of strings.
That's my code:

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;
}

I'm using like this:

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

It works fine.
But I can't pass numeric parameters to this function, only strings.
I need to change the function to work like this:

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

How can I do that?
How I get parameters with diferent types using va_arg()?

The solution I found until now is create a function int2str():

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

But I have to use this way:

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

otherwise, I got a memory leak...

I could use the function int2str() inside the function texto() but I don't know how to check the type of the parameters!

Ps.: I'm using C, not C++ for my code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执笏见 2024-12-19 03:18:26

如果您愿意采用 gcc 特定的解决方案,您可以将 int2str 更改为以下宏:

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

这意味着您可以编写:

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

而不泄漏。但它非常不便于携带。

If you're willing to take a gcc specific solution you can change int2str to be this macro:

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

This then means you can write:

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

without leaking. It's very non portable though.

橘虞初梦 2024-12-19 03:18:26

我怎样才能做到这一点?如何使用 va_arg() 获取不同类型的参数?

不幸的是,这是不可能的,当您使用变量参数列表时,类型信息会丢失。

一个非常简单的解决方案是使用声明“类型”的格式字符串,但话又说回来,为什么不简单地使用标准函数 snprintf 呢? 参考此处

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

How can I do that? How I get parameters with diferent types using va_arg()?

Unfortunately this is not possible, the type information gets lost when you are using variable argument lists.

One quite easy solution is to use a format string which declares the "types", but then again, why don't you simply use the standard function snprintf? Reference here.

char buffer[256];
snprintf(buffer, sizeof(buffer), "%s%s%d%s%f%s", "a", "b", 1, "d", 4.5, "e", NULL);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文