Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中连接字符串的安全方法是什么?_C_Arrays_String_Join - Fatal编程技术网

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

在C中连接字符串的安全方法是什么?,c,arrays,string,join,C,Arrays,String,Join,我需要从两个字符串构造文件的路径。我可以用这个(虽然没有测试): /*不要使用此代码*/ /*cmp是指组件*/ char*path_cmp1=“/Users/john/”; char*path_cmp2=“foo/bar.txt”; 无符号len=strlen(路径\u cmp1); char*path=path_cmp1; 对于(int i=0;i

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

/*不要使用此代码*/
/*cmp是指组件*/
char*path_cmp1=“/Users/john/”;
char*path_cmp2=“foo/bar.txt”;
无符号len=strlen(路径\u cmp1);
char*path=path_cmp1;
对于(int i=0;i

但我想这可能会导致内存损坏。是否有更好的方法来执行此操作,或者标准库中是否有用于此操作的函数?

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

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

strcat
strncat

string.h中的
strcat
如何?

#
#include <stdio.h> 

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

asprintf(&joined, "%s%s", a, b)
char*a=“你好”; char*b=“再见”; 字符*已加入; asprintf(已加入,“%s%s”,a,b)(&J)

但是它的可读性较差。

path
只是指向
path\u cmp1
的指针,您试图访问数组末尾以外的位置。偶尔这会起作用,但在绝大多数情况下,会导致内存损坏


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

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

+1 ... 但是
if(result){strcpy;strcat;}
如果malloc通过“写到位”失败,则自动返回NULL,您的意思是
join(join(“foo”,“bar”),“baz”)
?这将导致严重的内存泄漏。您的第二个示例不仅难看,而且由于缺少错误检查而不安全。@pmg在使用malloc时,我总是检查
NULL
。@larsman:不,我的意思是完全编写malloc、strcpy和strcat而不是join函数。这段代码扫描s1 3次,扫描s2两次,以找出它们的长度。如果您想要更快,只需扫描其中每一个。非标准,但在
snprintf
方面实现起来不太困难+1.是的,在两个
memcpy()。
char* result = malloc(strlen(s1) + strlen(s2) + 1);
assert(result);
strcat(strcpy(result, s1), s2);
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.
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;
}