2011-09-05 3 views
2

기본적으로 나는 대략 이와 같이 보이는 기능을 가지고 있으며 나는 밖으로 나가야합니다.함수에서 동적 C 스타일 문자열을 반환 하시겠습니까?

const char* UTF16ToUTF8(const wchar_t *in) { 
    int tmp = wcslen(in); 
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &in[0], (size_t)tmp, NULL, 0, NULL, NULL); 
    std::vector<char> out; 
    out.resize(size_needed); 
    WideCharToMultiByte(CP_UTF8, 0, &in[0], (size_t)tmp, &out[0], size_needed, NULL, NULL); 

    return &out[0]; 
} 

분명히 out은 참조 할 때 참조 해제됩니다. 내 옵션은 무엇입니까? 이 함수를 그렇게 호출 할 수 있어야합니다. 나는 절대적으로 스택에 머물고 싶습니다.

utf8outputfile << UTF16ToUTF8(wchar_tString) << endl; 
fprintf(utf8outputfile, "%s", UTF16ToUTF8(L"Mmm Mmm Unicode String κόσμε")); 
return UTF16ToUTF8(wchar_tString); 
+0

나는'std :: vecor'로 그렇게 할 수 있는지 몰랐다. 'WideCharToMultiByte'에'& out [0]'을 멀티 바이트 안전으로 전달합니까? 좋은 양식? – Sodved

+0

@Sodved no - 함수가 반환 될 때 벡터가 소멸되고 배킹 할당이 해제되기 때문에 블로우 업됩니다. 따라서이 함수의 결과는 유효한 할당을 가리 키지 않습니다. 벡터가 함수보다 오래 지속된다면 문자 벡터를 사용하여 문자열을 나타낼 수 있습니다 (대다수의 경우 std :: string이 더 적합 함). – justin

+1

@Sodved 그러나 vector는 연속적인 할당을 보장합니다. '& vec [0]'을 c 배열로 취급하는 것이 좋습니다. – justin

답변

6

그러한 걱정하지 문제가 자신을 수행하고 std::string 반환 :

printf("%s", UTF16ToUTF8(ws).c_str()); 

심지어 인수를 만들 것입니다 : 당신의 C 인터페이스, 사용, 그리고

std::string UTF16ToUTF8(const wchar_t *in) { 
    std::vector<char> out; 
    //... 
    return std::string(out.begin(), out.end()); // or std::string(out.data()) 
} 

을 함수 std::wstring을 사용하고 API 함수를 호출 할 때만 C 문자열을 추출하십시오.

begin/end 버전은 .data() 버전은 널 종료 문자열로 버퍼를 취급 ​​모든 문자가 포함되어 있습니다. 가장 적절한 것을 선택하십시오.

2

std :: string을 반환하면 내 첫 번째 선택 항목이됩니다.

그러나 절대적으로 긍정적으로 char *가 필요한 경우 몇 가지 옵션이 있습니다.

당신은 정말, 정말주의 발신자 항상 메모리 할당을 해제 있는지 확인되고, 힙에 새로운 숯불 *를 할당하고 그것을 반환 할 수 있습니다. 나는 명시 적으로이 소유권 이전을하게 될 어레이 우호적 인 boost auto_ptr equivalent가 있다고 생각한다.

또 다른 옵션은 발신자가 char * (및 최대 크기)를 전달하고 거기에 데이터를 입력하는 기능입니다. 따라서 호출자는 항상 메모리를 소유합니다.

또 다른 옵션은 호출자가 char ** (또는 char * &)를 전달하는 것이며, 함수는 호출자의 포인터에 메모리를 할당합니다. 이것은 소유권 이전을 명시 적으로 만듭니다. (호출자가 필요로하는 경우 크기를 보유 할 수있는 크기 (size_t &) 매개 변수가있을 수도 있습니다.

+0

아마 std :: string과 함께 갈 것입니다. 그러나, char * & 것이 흥미 롭습니다. 스택에 할당 할 수 있습니까? 함수에 대한 단일 호출로 스택에서 모든 작업을 수행 할 수 있다면 반환 값을 버릴 필요가 없습니다. – Riley