从函数返回动态C样式字符串?

时间:2011-09-05 02:11:15

标签: c++ winapi function c-strings

基本上我有一个大致看起来像这样的功能,我需要退出。

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

显然,退出时会被取消引用。我有什么选择?我需要能够像这样调用这个函数。我非常想留在堆栈中。

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

2 个答案:

答案 0 :(得分:6)

不要担心任何此类担忧并返回std::string

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

然后,在C界面中,使用:

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

我甚至会创建函数std::wstring的参数,并仅在调用API函数时提取C字符串。

begin/end版本包含所有字符,.data()版本将缓冲区视为以空字符结尾的字符串。选择最合适的。

答案 1 :(得分:2)

返回std :: string将是我的第一选择。

但是,如果你绝对需要char *,你有几种选择。

你可以在堆上分配一个新的char *并返回它,实际上,真的小心地确保调用者总是释放内存。我相信有一个提升auto_ptr等效的数组友好,可以明确这种所有权转移。

另一个选项是让调用者传入char *(和max size),以及将数据放入其中的函数。因此呼叫者总是拥有记忆。

另一个选项是让调用者传入char **(或char *&amp;),并且你的函数将内存分配给调用者的指针。这使得所有权转移明确。 (你也可以使用size(size_t&amp;)参数来保持大小,如果这是调用者可能需要的话。)