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

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

/* 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]; } 

但这可能会导致内存损坏。 有没有更好的方法来做到这一点,或者标准库中是否有这样的function?

 #include  #include  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); 

但这不太可读。

 #include  char *a = "hello "; char *b = "goodbye"; char *joined; asprintf(&joined, "%s%s", a, b) 

strcatstrncat

 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. 

这段代码有几个问题: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; } 

创建一个具有两个输入长度和strcpy / strcat输入的新字符串,并且不要忘记空终止符。

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

string.h中的strcat怎么样?

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

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