2013-08-28 2 views
1

현재 자신과 우리 팀이 std :: string을 사용하기 위해 리팩터링하고 싶지 않고 수정 된 char *를 사용하는 복잡한 함수가 있습니다. 어떻게하면 제대로 string :: c_str()을 char *로 deep copy 할 수 있을까요? 나는 이 아니며 문자열의 내부적으로 저장된 char *을 수정하려고합니다.deep copy std :: string :: c_str() to char *

char *cstr = string.c_str(); 

은 c_str()이 const이기 때문에 실패합니다.

+4

이 C++ 11입니까? 'std :: string'을 복사하고'& stringCopy [0]'을 사용하십시오. – chris

+1

'strdup','new/strcpy', @chris '제안, ... 선택의 여지가 있습니다. – syam

+0

sprintf (cstr, "% s", somestring.c_str()) – bartimar

답변

6

당신은 이런 식으로 작업을 수행 할 수 있습니다

const std::string::size_type size = string.size(); 
char *buffer = new char[size + 1]; //we need extra char for NUL 
memcpy(buffer, string.c_str(), size + 1); 
+6

* 문자열 크기에 대해 올바른 유형을 사용하십시오. 'std :: string :: size_type' 또는'std :: size_t'를 사용하십시오. – syam

+0

@syam ahh 당신은 절대적으로 맞습니다 :) –

+1

그것을 삭제하는 것을 잊지 마십시오. 또는 더 나은 방법은'std :: vector '을 사용하고, 배열을'v.data()'또는'& v [0]'으로 접근하는 것입니다. 또는 경계선이 정의되지 않은 동작을 신경 쓰지 않는다면 다른 문자열 ('string'). –

4

기존 기능을 수정하기보다는, 그냥 래퍼 역할을하는 오버로드를 만들 것입니다. 기존의 기능을 가정하면 내가 좋아하는 과부하 뭔가를 써서, ret_type f(char *)입니다 :

ret_type f(std::string s) { 
    return f(&s[0]); 
} 

참고 문자열의 복사본을 얻기 위해 소요 된 노력을 최소화하는 대신 참조 값으로 s을 전달합니다.

이론적으로 C++ 03까지는 이론상 작동이 보장되지 않습니다 (즉, 문자열의 버퍼가 연속적이라는 보장은 없습니다). 실제로 다른 사람이 수행 한 std::string 구현을 아는 사람이 아무도 없었기 때문에이 보증은위원회가 추가하기가 상당히 쉬웠습니다.

마찬가지로 이론적으로 NUL 터미네이터가 누락 될 수 있습니다. 그러나,

std::vector<char> tmp(string.begin(), string.end()); 
tmp.push_back('\0'); 
function(&tmp[0]); 

(I 오히려 같은 제리 관의 솔루션 : 그 가능성에 대해 우려된다면 대신 return f(const_cast<char *>(s.c_str()));을 사용하거나 반환하기 전에 s.push_back('\0');을 추가 할 수 있습니다

ret_type f(std::string s) { 
    s.push_back('\0'); 
    return f(&s[0]); 
} 
+0

래퍼 함수에서's.push_back ('\ 0')'을 할 것입니다. 그리고 당신은 분명히 마지막 코드에서'const_cast'를 의미했습니다. –

+0

@JamesKanze : 예, 물론입니다. –

1

확실한 솔루션입니다 .)

관련 문제