const char * 연결


116

다음과 같이 두 개의 const 문자를 연결해야합니다.

const char *one = "Hello ";
const char *two = "World";

어떻게하면 될까요?

char*C 인터페이스가있는 타사 라이브러리에서 이러한 s를 전달 받았으므로 std::string대신 사용할 수 없습니다 .


6
혼란 스럽습니다. 원래 질문자가 "c ++"태그를 썼고 다른 누군가가 그것을 제거했습니다. 이 질문에 대한 상황은 어떻습니까? C ++ 코드가 허용됩니까?
Johannes Schaub-litb

1
@Johannes : 더 나은 질문 xD입니다.
Prasoon Saurav

또한 원래 질문은 C를 언급하지 않았습니다. 해당 태그를 제거했습니다.

OP가 스택 strcpystrcat호출에서 배열을 사용하는 답변을 수락했기 때문에 C ++ 태그를 C 로 전환했으며 태그를 변경하는 것이 합리적이라고 생각했습니다.
Gregory Pakosz 2010 년

7
C C ++ 태그가 추가되었습니다 . OP가 주석에서 설명했듯이 그는 C ++ 코드를 작성하고 있지만 C 인터페이스를 사용하는 라이브러리를 호출하고 있습니다. 질문은 두 언어 모두에서 관련이 있습니다.
jalf

답변:


110

귀하의 예제에서 12 는 char 상수를 가리키는 char 포인터입니다. 이 포인터가 가리키는 char 상수는 변경할 수 없습니다. 그래서 다음과 같습니다.

strcat(one,two); // append string two to string one.

작동 안 할 것이다. 대신 결과를 보관할 별도의 변수 (char 배열)가 있어야합니다. 이 같은:

char result[100];   // array to hold the result.

strcpy(result,one); // copy string one into the result.
strcat(result,two); // append string two to the result.

7
char * 결과는 어떻습니까; 결과 = calloc (strlen (one) + strlen (two) +1, sizeof (char)); 그리고 strcpy + strcat?
luiscubal

3
@luiscubal : 그래도 작동 할 것입니다 ... calloc이 void *를 반환하므로 (char *) 캐스트를 사용하십시오.
codaddict

5
이 답변의 문제는 하드 코딩 된 배열 크기입니다. 특히 "1"과 "2"가 어떤 크기인지 모를 경우에는 들어가기에 정말 나쁜 습관입니다.
Paul Tomblin

1
첫 번째 예에서는 strcpy(one,two);이어야한다 strcat(one,two);(하지 않는 것이 올바르게 지적으로, 그것을 수정합니다).
Alok Singhal

1
어떤 약 sprintf(dest,"%s%s",one,two)및 복사를 잊어?
mpen 2010 년

81

C 방식 :

char buf[100];
strcpy(buf, one);
strcat(buf, two);

C ++ 방식 :

std::string buf(one);
buf.append(two);

컴파일 타임 방식 :

#define one "hello "
#define two "world"
#define concat(first, second) first second

const char* buf = concat(one, two);

31

C ++를 사용 std::string하는 경우 C 스타일 문자열 대신 사용하지 않는 이유는 무엇입니까?

std::string one="Hello";
std::string two="World";

std::string three= one+two;

이 문자열을 C 함수에 전달해야하는 경우 three.c_str()


7
내가 C로 코딩 된 라이브러리를 사용하고 있기 때문에 그래서 기능 * const를 문자를 반환
Anthoni 콜드웰

1
@AnthoniCaldwell : 웃어 주셔서 감사합니다. 내가하지 때문에 작업 pressure.:D의 수
Rick2047

새 직장을 구할 때처럼 들리나요? ...
최대

20

사용 std::string:

#include <string>

std::string result = std::string(one) + std::string(two);

10
두 번째 명시 적 생성자 호출 할 필요가 없습니다
sellibitze

17
const char *one = "Hello ";
const char *two = "World";

string total( string(one) + two );

// to use the concatenation as const char*, use:
total.c_str()

업데이트 : 변경 string total = string(one) + string(two);string total( string(one) + two );(문자열이 임시 문자열 전체의 건설을 피할 수) 성능상의 이유로

// string total(move(move(string(one)) + two));  // even faster?

@iburidu 측정 했습니까? 안전이 성능보다 중요한 상황은 어떻습니까? (일반적인 상황)
Sqeaky

3
@Sqeaky 이것이 다른 솔루션보다 안전한 상황은 전혀 없지만 런타임 동작을 호출하고 거의 확실히 메모리 할당을 호출하여 컴파일 시간 솔루션보다 항상 느립니다.
앨리스

8

또 하나의 예 :

// calculate the required buffer size (also accounting for the null terminator):
int bufferSize = strlen(one) + strlen(two) + 1;

// allocate enough memory for the concatenated string:
char* concatString = new char[ bufferSize ];

// copy strings one and two over to the new buffer:
strcpy( concatString, one );
strcat( concatString, two );

...

// delete buffer:
delete[] concatString;

그러나 특별히 C ++ 표준 라이브러리를 원하지 않거나 사용할 수없는 경우가 아니면 사용하는 std::string것이 더 안전 할 것입니다.


1
OP가 C ++를 사용할 수 없으면 new. 그리고 그가 그것을 사용할 수 있다면 그는 std::string당신이 말한 것처럼 사용해야합니다 .
Alok Singhal

5

C 라이브러리와 함께 C ++를 사용하는 것 같으므로 const char *.

나는 그것들 const char *std::string다음과 같이 포장하는 것이 좋습니다 .

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d;

5

우선 동적 메모리 공간을 만들어야합니다. 그런 다음 두 문자열을 그 안에 strcat 할 수 있습니다. 또는 C ++ "문자열"클래스를 사용할 수 있습니다. 구식 C 방식 :

  char* catString = malloc(strlen(one)+strlen(two)+1);
  strcpy(catString, one);
  strcat(catString, two);
  // use the string then delete it when you're done.
  free(catString);

새로운 C ++ 방식

  std::string three(one);
  three += two;

왜 동적 메모리가 필요합니까?
Luca Matteis

4
-1, 먼저 C-way로 malloc을 사용하고 무료로 사용해야합니다. 그러면 새로 작성하더라도 삭제가 아니라 delete []이어야합니다.
Naveen

내가 사용하는 라이브러리는 C ++가 아닌 C로 코딩되어 있으므로 모든 함수는 문자열이 아닌 const char *를 반환합니다.
Anthoni Caldwell

1
@Naveen, 태그는 "C ++"라고 말했습니다. new와 delete를 사용할 수 없다면 그는 C ++ 태그를 사용하지 않았어야합니다.
Paul Tomblin

5

문자열의 크기를 모르는 경우 다음과 같이 할 수 있습니다.

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

int main(){
    const char* q1 = "First String";
    const char* q2 = " Second String";

    char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char));
    strcpy(qq,q1);
    strcat(qq,q2);

    printf("%s\n",qq);

    return 0;
}

3

사용할 수 있습니다 strstream. 공식적으로 더 이상 사용되지 않지만 C 문자열로 작업해야하는 경우 여전히 훌륭한 도구라고 생각합니다.

char result[100]; // max size 100
std::ostrstream s(result, sizeof result - 1);

s << one << two << std::ends;
result[99] = '\0';

이것은 스트림에 쓴 one다음 two\0사용하여 종료 를 추가합니다 std::ends. 두 문자열이 모두 정확히 99문자 를 쓸 수있는 경우 - 쓰기 공간이 남지 않도록 \0-마지막 위치에 수동으로 하나를 씁니다.


지원 중단은 그다지 중요하지 않습니다. 표준의 차기 버전에서 제거 되더라도 자신의 네임 스페이스에서 다시 구현하는 것은 그리 많은 작업이 아닙니다.
Steve Jessop

@Steve, 실제로 :)와 streambuf함께 사용되는 char 버퍼에 직접 출력을 쓰는 ostream것도 그리 어렵지 않습니다.
Johannes Schaub-litb

3
const char* one = "one";
const char* two = "two";
char result[40];
sprintf(result, "%s%s", one, two);

0

동적 메모리 할당에서 strcpy 명령을 사용하지 않고 두 개의 상수 char 포인터 연결 :

const char* one = "Hello ";
const char* two = "World!";

char* three = new char[strlen(one) + strlen(two) + 1] {'\0'};

strcat_s(three, strlen(one) + 1, one);
strcat_s(three, strlen(one) + strlen(two) + 1, two);

cout << three << endl;

delete[] three;
three = nullptr;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.