0

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

我有如下代码:

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

我想创建一个名为“graph.eps”的新char*变量,由上面给出的两个变量组成。如何才能做到这一点?fileName1WithExtension1char*

4

6 回答 6

4
char *new_string;

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

...

free(new_string)
于 2013-03-13T20:46:32.517 回答
4

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

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

然后简单地

std::string fileName1WithExtension1 = filename1 + extension1;

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

真的没有理由在 C++ 代码中使用纯 C 字符串。它非常容易出错和乏味,应该积极避免。

于 2013-03-13T20:56:36.403 回答
2

您可以使用该asprintf()功能

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

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

free(buffer);
于 2013-03-13T20:46:28.700 回答
2
char *joined;
joined = (char*)malloc(strlen(fileName1) + strlen(extension1) + 1);
strcpy(joined, fileName1)
strcat(joined, extension1)

为了小幅提高性能,如果编译器在优化方面足够聪明,请将最后一行更改为

strcpy(joined+strlen(fileName1), extension1)

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

于 2013-03-13T20:51:02.620 回答
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;
}
于 2013-03-13T22:26:24.613 回答
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,其签名看起来像:

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

在您的问题的上下文中调用哪个会更好:

char *fileName1WithExtension1 = astrjoin_va(NULL, "", fileName1, extension1, NULL);
于 2013-03-14T11:27:13.727 回答