在C中连接字符串文字

时间:2018-04-06 23:56:48

标签: c

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

int main() {
    char *a = "3";
    char *b = "2";
    strcat(a, b);
    printf("%s\n", a);
return 0;
}

运行此代码,会出现seg错误。我尝试了strcpy(a,b)但它也给出了同样的错误。

有什么方法可以改变=&#34; 3&#34;到a =&#34; 32&#34; ?

2 个答案:

答案 0 :(得分:2)

这两个变量

char *a = "3";
char *b = "2";

指向字符串文字,你不能修改字符串文字 未定义的行为。在大多数情况下,字符串文字以只读方式存储 内存,所以修改它们通常以段错误结束。

如果要连接字符串,则需要第二个字符串的空间。

第一个解决方案:创建更大的数组:

char a[20] = "3";
char b[20] = "2";

strcat(a, b);
puts(a);

这将打印32

此解决方案的问题在于,如果b太长,那么它就不合适了 进入a,您将溢出a。例如,如果您正在阅读 用户,用户可能会输入长度超过a的字符串。在那里面 应使用案例strncat或查看我的第二个解决方案。

第二种解决方案:动态分配内存

int main(void)
{
    const char *a = "3";
    const char *b = "2";

    char *dest = malloc(strlen(a) + 1);

    if(dest == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        return 1;
    }

    strcpy(dest, a);

    char *tmp = realloc(a, strlen(a) + strlen(b) + 1);
    if(tmp == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        free(dest);
        return 1;
    }

    dest = tmp;

    strcat(dest, b);

    // printing concatenated string
    puts(dest);

    free(dest);

    return 0;
}

另一个解决方案是

int main(void)
{
    const char *a = "3";
    const char *b = "2";

    size_t len = strlen(a) + strlen(b);

    // using calloc instead of malloc, because
    // calloc sets the allocated memory to 0,
    // great initialization for when using strcat
    char *dest = calloc(len + 1, 1);

    if(dest == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        return 1;
    }

    strcat(dest, a);
    strcat(dest, b);

    // printing concatenated string
    puts(dest);

    free(dest);

    return 0;
}

或者你也可以像这样使用snprintf

int main(void)
{
    const char *a = "3";
    const char *b = "2";

    int len = snprintf(NULL, 0, "%s%s", a, b);

    char *dest = malloc(len + 1);

    if(dest == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        return 1;
    }

    sprintf(dest, "%s%s", a, b);

    // printing concatenated string
    puts(dest);

    free(dest);

    return 0;
}

此解决方案使用的事实是,当您将NULL和0作为第一个传递时 参数snprintf,此函数将返回该字符的数量 结果字符串将需要,因此您可以使用该函数来确定 连接字符串的总长度。如果您愿意,这个解决方案很棒 连接不同的类型,例如用数字连接字符串。

通常,有许多方法可以连接字符串,您可以使用哪种方法 取决于您的需求:您如何阅读数据,您想要做什么 连接,无论你是否使用字符串文字等。

答案 1 :(得分:0)

您正在获得分段错误,因为a是一个指向字符串文字"3"的指针,它可以存储在只读存储中,而不是指向可以保存连接的有效内存位置串。在进行连接时,您需要确保目标缓冲区应足够大以包含连接的结果字符串 你可以这样做:

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

int main() {
    char *a = "3";
    char *b = "2";
    char *buf;

    buf = malloc (strlen(a) + strlen(b) + 1);  // + 1 is to accommodate null terminating character
    if (buf == NULL) {
        exit(EXIT_FAILURE);
    }

    sprintf (buf, "%s%s", a, b);
    printf ("%s\n", buf);

    free (buf);
    return 0;
}