C에서 두 개의 문자열을 어떻게 연결합니까?


141

두 줄을 어떻게 추가합니까?

시도 name = "derp" + "herp";했지만 오류가 발생했습니다.

식은 정수 또는 열거 형이어야합니다

답변:


184

C는 다른 언어가 지원하는 문자열을 지원하지 않습니다. C의 문자열 char은 첫 번째 null 문자로 끝나는 배열에 대한 포인터 입니다. 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-복원 모니카

2
를 사용하여 첫 번째 버전의 성능이 약간 향상 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

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로 정의되어 있기 때문에 곱하기의 정체성 덕분에 여기서 벗어날 수 있습니다.
Andy

"크기"코드에 적합한 유형 인 int len-> size_t len를 고려하십시오 size_t. 또한 // room for NULL-> // room for null character NULL는 널 포인터를 의미합니다.
chux-복원 모니카

10

일회성에 필요한 것으로 가정하겠습니다. PC 개발자 인 것으로 가정하겠습니다.

스택을 사용하세요, 루크 어디서나 사용하십시오. , malloc에 / 작은 할당에 대한 무료 사용하지 마십시오 이제까지 .

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

문자열 당 10KB로 충분하지 않으면 크기에 0을 추가하고 신경 쓰지 마십시오. 어쨌든 스코프의 끝에서 스택 메모리를 해제합니다.


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;
}

자세한 내용은 malloc , freeasprintf 를 참조하십시오.


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에서 두 문자열을 연결하는 것은 적어도 세 가지 방법으로 수행 할 수 있습니다.

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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.