从两个旧的char *中制作一个新的char *

时间:2013-03-13 20:43:38

标签: c++ c char concatenation

我愿意使用中间C ++代码,但C代码是首选。

我的代码如下:

char *fileName1 = "graph";
char *extension1 = ".eps";

我想创建一个名为char*的新fileName1WithExtension1变量,它对应于“graph.eps”,由上面给出的两个char*变量组成。怎么办呢?

6 个答案:

答案 0 :(得分:4)

char *new_string;

new_string = malloc(strlen(fileName1) + strlen(extension1) + 1);
sprintf(new_string, "%s%s", fileName1, extension1);

...

free(new_string)

答案 1 :(得分:4)

如果您使用C ++,请将其作为std::string字符串:

std::string fileName1 = "graph";
std::string extension1 = ".eps";

然后简单地

std::string fileName1WithExtension1 = filename1 + extension1;

如果您需要将其传递给期望C字符串的C库函数,请使用fileName1WithExtension1.c_str()获取char指针

没有理由在C ++代码中使用普通的C字符串。这是非常容易出错和繁琐的,应该积极地避免它。

答案 2 :(得分:2)

您可以使用asprintf()功能

char *buffer;
asprintf (&buffer, "%s%s", fileName1, extension1);

buffer变量在代码中变得无用时,你必须通过asprintf释放为缓冲区分配的内存

free(buffer);

答案 3 :(得分:2)

char *joined;
joined = (char*)malloc(strlen(fileName1) + strlen(extension1) + 1);
strcpy(joined, fileName1)
strcat(joined, extension1)

如果性能提升很小,如果编译器在优化时足够聪明,请将最后一行更改为

strcpy(joined+strlen(fileName1), extension1)

更好的是,在第一次确定变量时将fileName1的长度存储在变量中,并在最终的strcpy()中使用它。

答案 4 :(得分:1)

如果你想真正的低级别,有丑陋的循环等,你可以这样做:(经过测试,它编译并给出预期和期望的结果)

char* filename1 = "graph";
char* extension1 = ".eps";
char* filename1WithExtension1 = combine(filename1, extension1);

其中:

char* combine(char* str1, char* str2)
{
    int str1len = 0, str2len = 0;
    while(str1[str1len] != '\0') {
        str1len++;
    }
    while(str2[str2len] != '\0') {
        str2len++;
    }
    int outputlen = str1len + str2len + 1;
    char* output = new char[outputlen];
    for(int i = 0; i < str1len; i++)
    {
        output[i] = str1[i];
    }
    for(int i = str1len; i < outputlen; i++)
    {
        output[i] = str2[i - str1len];
    }
    return output;
}

答案 5 :(得分:1)

我做了一些C刷子以获得乐趣,这里是一个替代(C90和C ++兼容代码),用于连接带有分隔符的C字符串数组。任何体面优化的编译器都应该非常高效:

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

/* **parts are strings to join, a NULL-terminated array of char*
 * sep is separator string, use "" for no separator, must not be NULL
 * returns malloc-allocated buffer which must be freed
 * if len_out!=NULL, sets *len_out to strlen of result string */
char *astrjoin(int *len_out, const char *sep, char **parts) {

    int part_count;
    int parts_total_len = 0;

    for(part_count = 0; parts[part_count]; ++part_count) {
        parts_total_len += strlen(parts[part_count]);
    }
    if (part_count > 0) {
        int malloc_size = (part_count - 1) * strlen(sep) + parts_total_len + 1;
        char *result = (char*)malloc(malloc_size);
        char *dest = result;   
        for(;;) {
            const char *src;
            for(src=*parts; *src; ++src) *dest++ = *src;
            if (!*++parts) break;
            for(src=sep ; *src; ++src) *dest++ = *src;
        }
        *dest = 0;
        if (len_out) *len_out = malloc_size - 1;
        return result;
    } else {
        if (len_out) *len_out = 0;
        return strdup("");
    }
}

使用示例:

int main(int argc, char *argv[]) {
    /* argv is NULL-terminated array of char pointers */
    char *commandline = astrjoin(NULL, " ", argv);
    printf("argc: %d\nargv: %s\n", argc, commandline);
    free(commandline);
    return 0;
}

要在问题的上下文中调用它,它可能类似于:

char *tmparr[] = { fileName1, exteansion1, NULL };
char *fileName1WithExtension1 = astrjoin(NULL, "", tmparr);

创建一个删除了sep和/或len_out的版本,或者支持“varargs”的版本,其签名看起来像是这样的,这将是微不足道的:

char *astrjoin_va(int *len_out, const char *sep, ...);

在你的问题的背景下打电话会更好:

char *fileName1WithExtension1 = astrjoin_va(NULL, "", fileName1, extension1, NULL);