在C中连接字符串的安全方法是什么?

时间:2011-03-10 15:48:59

标签: c arrays string join

我需要从两个字符串构造一个文件的路径。我可以使用它(虽然没有经过测试):

/* DON'T USE THIS CODE! */
/* cmp means component */
char *path_cmp1 = "/Users/john/";
char *path_cmp2 = "foo/bar.txt";
unsigned len = strlen(path_cmp1);
char *path = path_cmp1;
for (int i = 0; i < strlen(path_cmp2); i++) {
  path[len + i] = path_cmp2[i];
}

但这可能导致内存损坏我猜。有更好的方法可以做到这一点,还是在标准库中有这个功能?

9 个答案:

答案 0 :(得分:9)

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

char *join(const char* s1, const char* s2)
{
    char* result = malloc(strlen(s1) + strlen(s2) + 1);

    if (result) // thanks @pmg
    {
        strcpy(result, s1);
        strcat(result, s2);
    }

    return result;
}

这很简单,可以编写到位,特别是当你有多个字符串连接时。

请注意,这些函数返回其目标参数,因此您可以编写

char* result = malloc(strlen(s1) + strlen(s2) + 1);
assert(result);
strcat(strcpy(result, s1), s2);

但这不太可读。

答案 1 :(得分:5)

#include <stdio.h> 

char *a = "hello ";
char *b = "goodbye";
char *joined;

asprintf(&joined, "%s%s", a, b)

答案 2 :(得分:4)

此代码中存在以下几个问题: 1 - 在for循环上调用strlen是一个坏主意,它会在每次迭代时计算字符串长度,因此最好在循环之前调用它一次并将结果保存在变量中。

2 - 相同的strlen问题适用于循环内的strlen(path_cmp1),在循环之前调用它并递增其大小。

最后,最好简单地复制两个字符串并将它们存储在动态分配的字符串中,例如:

char *join_strings(const char* s1, const char* s2)
{
    size_t lens1 = strlen(s1);
    size_t lens2 = strlen(s2);

    //plus 1 for \0
    char *result = malloc(lens1 + lens2 + 1);

    if(result)
    {
        memcpy(result, s1, lens1);
        memcpy(result+lens1, s2, lens2+1);
    }

    //do not forget to call free when do not need it anymore
    return result;
}

答案 3 :(得分:3)

strcatstrncat

答案 4 :(得分:3)

char *path_cmp1 = "/Users/john/";
char *path_cmp2 = "foo/bar.txt";

int firstLength = strlen(path_cmp1);
int secondLength = strlen(path_cmp2);
char *both = malloc(firstLength+secondLength+1);
memcpy(both, path_cmp1, firstLength);
memcpy(both+firstLength, path_cmp2, secondLength+1);
       // this +1 copyes the second string's null-terminator too.

答案 5 :(得分:2)

创建一个新的字符串,其长度为两个输入,strcpy / strcat为输入,不要忘记null终止符。

答案 6 :(得分:2)

使用strcat。 (你的代码会导致内存损坏,你说得对。)

答案 7 :(得分:2)

string.h中的strcat怎么样?

答案 8 :(得分:2)

path只是指向path_cmp1的指针,您试图访问超出数组末尾的内容。偶尔这会起作用,但在绝大多数情况下,你会导致内存损坏。

正如其他人指出的那样,使用strcat来连接字符串。