从函数返回一个动态的C风格字符串

Returning a dynamic C style string from a function?

本文关键字:动态 风格 字符串 一个 返回 函数      更新时间:2023-10-16

基本上我有一个函数,大致看起来像这样,我需要返回。

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

不要担心这些问题,返回一个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()版本将缓冲区视为以空结束的字符串。选择最合适的

返回std::string将是我的首选。

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

您可以在堆上分配一个新的char*并返回它,因此,确实小心地确保调用者总是释放内存。我相信有一个boost auto_ptr等效的数组友好的,可以显式地进行这种所有权转移。

另一个选项是调用者传入char*(和max size),然后函数将数据放入其中。因此,调用者始终拥有内存。

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