在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)
有strcat
和strncat
。
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
来连接字符串。