如何在C中串联两个字符串?


141

如何添加两个字符串?

我试过了 name = "derp" + "herp";,但出现错误:

表达式必须具有整数或枚举类型

Answers:


184

C没有某些其他语言支持的字符串。C中的字符串只是指向以char第一个空字符终止的数组的指针。C中没有字符串连接运算符。

使用strcat连接两个字符串。您可以使用以下功能来做到这一点:

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

char* concat(const char *s1, const char *s2)
{
    char *result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator
    // in real code you would check for errors in malloc here
    strcpy(result, s1);
    strcat(result, s2);
    return result;
}

这不是最快的方法,但是您现在不必为此担心。请注意,该函数将堆分配的内存块返回给调用方,并传递该内存的所有权。free不再需要调用者时,它对存储器有责任。

像这样调用函数:

char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string

如果确实受到性能的困扰,那么您将希望避免重复扫描输入缓冲区以寻找空终止符。

char* concat(const char *s1, const char *s2)
{
    const size_t len1 = strlen(s1);
    const size_t len2 = strlen(s2);
    char *result = malloc(len1 + len2 + 1); // +1 for the null-terminator
    // in real code you would check for errors in malloc here
    memcpy(result, s1, len1);
    memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator
    return result;
}

如果您打算对字符串进行大量工作,那么最好使用对字符串具有一流支持的另一种语言。


1
一点点:代码可以最后复制字符串的第一部分,然后复制return memcpy(result, s1, len1);。尽管进行了微优化或至少进行了一些代码打高尔夫球,但鉴于其基本用途,这种潜在的改进可能会有价值。
chux-恢复莫妮卡

1
使用改进了第一个版本的性能,该版本stpcpy返回了指向第一个字符串末尾的指针:strcpy(stpcpy(result, s1), s2);
Daniel

17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}

1
它也适用于c中的宏,值得注意的是
Abe Fehr 2013年

15

David Heffernan 在回答中解释了这个问题,我编写了改进的代码。见下文。

通用功能

我们可以编写一个有用的可变参数函数来连接任意数量的字符串:

#include <stdlib.h>       // calloc
#include <stdarg.h>       // va_*
#include <string.h>       // strlen, strcpy

char* concat(int count, ...)
{
    va_list ap;
    int i;

    // Find required length to store merged string
    int len = 1; // room for NULL
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
        len += strlen(va_arg(ap, char*));
    va_end(ap);

    // Allocate memory to concat strings
    char *merged = calloc(sizeof(char),len);
    int null_pos = 0;

    // Actually concatenate strings
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
    {
        char *s = va_arg(ap, char*);
        strcpy(merged+null_pos, s);
        null_pos += strlen(s);
    }
    va_end(ap);

    return merged;
}

用法

#include <stdio.h>        // printf

void println(char *line)
{
    printf("%s\n", line);
}

int main(int argc, char* argv[])
{
    char *str;

    str = concat(0);             println(str); free(str);
    str = concat(1,"a");         println(str); free(str);
    str = concat(2,"a","b");     println(str); free(str);
    str = concat(3,"a","b","c"); println(str); free(str);

    return 0;
}

输出:

  // Empty line
a
ab
abc

清理

请注意,当不需要时,应释放已分配的内存,以避免内存泄漏:

char *str = concat(2,"a","b");
println(str);
free(str);

3
calloc的参数是向后的。他们应该先数然后再大小。你逃掉了在这里感谢乘身份,因为的sizeof(char)的定义为1
安迪

考虑int len- > size_t lensize_t是“大小”的代码正确的类型。另外// room for NULL-> // room for null character NULL表示空指针。
chux-恢复莫妮卡

9

我假设您需要一次性的东西。我假设您是PC开发人员。

使用堆栈,卢克。随处使用。永远不要对小分配使用malloc / free 。

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

#define STR_SIZE 10000

int main()
{
  char s1[] = "oppa";
  char s2[] = "gangnam";
  char s3[] = "style";

  {
    char result[STR_SIZE] = {0};
    snprintf(result, sizeof(result), "%s %s %s", s1, s2, s3);
    printf("%s\n", result);
  }
}

如果每个字符串10 KB不够用,请为该大小添加一个零,并且不要打扰-无论如何,它们将在范围的末尾释放其堆栈内存。


1
这将更清楚地表示为snprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
MM

8

您应该使用strcat,或者更好strncat。谷歌它(关键字是“串联”)。


8
当心:这strncat()是一个很难使用的功能。快速,不用看手册,您指定什么长度strncat()?如果您说“缓冲区的长度”,那么您就很好地说明了我的观点。它具有违反直觉的界面,当您有足够的数据安全使用它时,您无需首先使用该功能-可以使用其他更快捷有效的替代方法(例如strcpy()memmove())代替。几乎所有“我应该使用什么”的问题strncat()都不是答案。
Jonathan Leffler

5

您不能像在C中那样添加字符串文字。您必须创建一个缓冲区,该缓冲区的大小为字符串文字1 +字符串文字2 +一个字节用于空终止符,并将相应的文字复制到该缓冲区,并确保其为空终止。或者,您可以使用类似的库函数strcat


3

没有GNU扩展名:

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

int main(void) {
    const char str1[] = "First";
    const char str2[] = "Second";
    char *res;

    res = malloc(strlen(str1) + strlen(str2) + 1);
    if (!res) {
        fprintf(stderr, "malloc() failed: insufficient memory!\n");
        return EXIT_FAILURE;
    }

    strcpy(res, str1);
    strcat(res, str2);

    printf("Result: '%s'\n", res);
    free(res);
    return EXIT_SUCCESS;
}

或者使用GNU扩展:

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

int main(void) {
    const char str1[] = "First";
    const char str2[] = "Second";
    char *res;

    if (-1 == asprintf(&res, "%s%s", str1, str2)) {
        fprintf(stderr, "asprintf() failed: insufficient memory!\n");
        return EXIT_FAILURE;
    }

    printf("Result: '%s'\n", res);
    free(res);
    return EXIT_SUCCESS;
}

有关更多详细信息,请参见mallocfreeasprintf


2
#include <string.h>
#include <stdio.h>
int main()
{
   int a,l;
   char str[50],str1[50],str3[100];
   printf("\nEnter a string: ");
   scanf("%s",str);
   str3[0]='\0';
   printf("\nEnter the string which you want to concat with string one: ");
   scanf("%s",str1);
   strcat(str3,str);
   strcat(str3,str1);
   printf("\nThe string is %s\n",str3);
}

2

连接字符串

在C中连接任意两个字符串可以通过至少3种方式完成:

1)通过将字符串2复制到字符串1的末尾

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX];
  int i,j=0;
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  for(i=strlen(str1);str2[j]!='\0';i++)  //Copying string 2 to the end of string 1
  {
     str1[i]=str2[j];
     j++;
  }
  str1[i]='\0';
  printf("\nConcatenated string: ");
  puts(str1);
  return 0;
}

2)通过将字符串1和字符串2复制到字符串3

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX],str3[MAX];
  int i,j=0,count=0;
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  for(i=0;str1[i]!='\0';i++)          //Copying string 1 to string 3
  {
    str3[i]=str1[i];
    count++;
  }
  for(i=count;str2[j]!='\0';i++)     //Copying string 2 to the end of string 3
  {
    str3[i]=str2[j];
    j++;
  }
  str3[i]='\0';
  printf("\nConcatenated string : ");
  puts(str3);
  return 0;
}

3)通过使用strcat()函数

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX];
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  strcat(str1,str2);                    //strcat() function
  printf("\nConcatenated string : ");
  puts(str1);
  return 0;
}

0

在C语言中,您实际上没有字符串,作为通用的一流对象。您必须将它们作为字符数组进行管理,这意味着您必须确定如何管理数组。一种方法是使用普通变量,例如放置在堆栈上。另一种方法是使用malloc

排序后,可以将一个数组的内容复制到另一个数组,以使用strcpy或连接两个字符串strcat

话虽如此,C确实具有“字符串文字”的概念,这是在编译时已知的字符串。使用时,它们将是放置在只读存储器中的字符数组。但是,可以通过将两个字符串文字彼此相邻写入来连接它们,如中所述"foo" "bar",这将创建字符串文字“ foobar”。


0

使用memcpy

char *str1="hello";
char *str2=" world";
char *str3;

str3=(char *) malloc (11 *sizeof(char));
memcpy(str3,str1,5);
memcpy(str3+strlen(str1),str2,6);

printf("%s + %s = %s",str1,str2,str3);
free(str3);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.