复制宽字符串
Duplicating wide-character string
我正在尝试创建一个应用程序,在该应用程序中我有一个函数,我正在尝试复制一个宽字符串。我目前正在使用 _wcsdup()
,因为它是一个 Windows 应用程序,并且一切正常。但是我需要创建一个多平台函数,所以 _wcsdup()
(这是一个 Windows 函数)对我来说不可行。
现在,我的代码看起来像这样:
wchar_t* out = _wcsdup(wstring.str().c_str());
其中 wstring
是字符串流。
现在,我正在寻找 Windows 和 Linux 的通用函数,以使该函数正常工作。
标准的跨平台等效项是 allocate/free 使用 new[]
/delete[]
的 wchar_t[]
缓冲区(或者,如果绝对需要,malloc()
/free()
以反映 _wcsdup()
的行为),使用 std::copy()
或 std::memcpy()
将字符从 wstring
复制到该缓冲区,例如:
std::wstring w = wstring.str();
wchar_t* out = new wchar_t[w.size()+1];
std::copy(w.begin(), w.end(), out);
w[w.size()] = L'[=10=]';
...
delete[] out;
/*
std::wstring w = wstring.str();
wchar_t* out = (wchar_t*) malloc((w.size() + 1) * sizeof(wchar_t));
std::copy(w.begin(), w.end(), out);
w[w.size()] = L'[=10=]';
...
free(out);
*/
std::wstring w = wstring.str();
size_t size = w.size() + 1;
wchar_t* out = new wchar_t[size];
std::memcpy(out, w.c_str(), size * sizeof(wchar_t));
...
delete[] out;
/*
std::wstring w = wstring.str();
size_t size = (w.size() + 1) * sizeof(wchar_t);
wchar_t* out = (wchar_t*) malloc(size);
std::memcpy(out, w.c_str(), size);
...
free(out);
*/
但是,无论哪种方式,因为 str()
returns 一个 std::wstring
开始,你最好坚持使用 std::wstring
而不是使用 wchar_t*
全部:
std::wstring out = wstring.str();
如果你需要 (const) wchar_t*
,你可以使用 out.c_str()
或 out.data()
,例如当将 out
传递给采用空终止字符串的 C 风格函数时指针。
假设需要将字符串传递给期望 free
它的函数,您可以使用 malloc
和 memcpy
:
auto const ws = wstring.str();
auto const ptr = std::malloc(sizeof wchar_t * (ws.size() + 1));
std::memcpy(ptr, ws.c_str(), sizeof wchar_t * (ws.size() + 1));
// pass ptr to another function, or std::free(ptr)
+ 1
是考虑空终止符,size()
中没有。
传统的方法是在你的程序中有一个配置系统,告诉你平台有什么和没有什么:
在一些专门用于可移植性的源文件中,您有:
#if !HAVE_WCSDUP
wchar_t *wcsdup(const wchar_t *orig)
{
#if HAVE_MICROSOFT_WCSDUP
return _wcsdup(orig);
#else
size_t nwch = wcslen(orig) + 1;
wchar_t *copy = wmalloc(nwch);
if (copy)
wmemcpy(copy, orig, nwch);
return copy;
#endif
}
#endif
在一些头文件(也包括在上面)中,你有这个:
#if !HAVE_WSCDUP
extern "C" wchar_t wcsdup(const wchar_t *);
#endif
提供缺少的声明。一种可能的方法也是这样。在头文件中,你做:
#if HAVE_WCSDUP
// nothing to provide
#elif HAVE_MICROSOFT_WCSDUP
// just alias to the Microsoft one via #define
#define wcsdup _wcsdup
#else
// declare ours: provided in portability.cc
extern "C" wchar_t wcsdup(const wchar_t *);
#endif
然后在portability.cc
:
#if !HAVE_WCSDUP && !HAVE_MICROSOFT_WCSDUP
wchar_t *wcsdup(const wchar_t *orig)
{
size_t nwch = wcslen(orig) + 1;
wchar_t *copy = wmalloc(nwch);
if (copy)
wmemcpy(copy, orig, nwch);
return copy;
}
#endif
您需要围绕您的程序构建配置系统来提供这些 HAVE_
常量的值。在某些系统上,shell 脚本可以检查环境并将它们扔到 config.h
中。对于某些系统,您可以使用固定配置;例如在 Windows 上构建的配置步骤可能包括将手动维护的 config-msvc.h
复制到 config.h
。在 config-msvc.h
你有:
#define HAVE_MICROSOFT_WCSDUP 1
我假设您需要一个 malloc
重复的字符串,因为与一些消耗一个的 API 进行通信。因此,在我的回答中,我没有自以为是地使用 C++ 库功能来解决问题。
然而,在 C++ 代码中,我们可能应该将 C 函数称为 std::wcslen
等等。或者 portability.cc
可以只是 portability.c
,如果它提供缺少的 C 函数。
我正在尝试创建一个应用程序,在该应用程序中我有一个函数,我正在尝试复制一个宽字符串。我目前正在使用 _wcsdup()
,因为它是一个 Windows 应用程序,并且一切正常。但是我需要创建一个多平台函数,所以 _wcsdup()
(这是一个 Windows 函数)对我来说不可行。
现在,我的代码看起来像这样:
wchar_t* out = _wcsdup(wstring.str().c_str());
其中 wstring
是字符串流。
现在,我正在寻找 Windows 和 Linux 的通用函数,以使该函数正常工作。
标准的跨平台等效项是 allocate/free 使用 new[]
/delete[]
的 wchar_t[]
缓冲区(或者,如果绝对需要,malloc()
/free()
以反映 _wcsdup()
的行为),使用 std::copy()
或 std::memcpy()
将字符从 wstring
复制到该缓冲区,例如:
std::wstring w = wstring.str();
wchar_t* out = new wchar_t[w.size()+1];
std::copy(w.begin(), w.end(), out);
w[w.size()] = L'[=10=]';
...
delete[] out;
/*
std::wstring w = wstring.str();
wchar_t* out = (wchar_t*) malloc((w.size() + 1) * sizeof(wchar_t));
std::copy(w.begin(), w.end(), out);
w[w.size()] = L'[=10=]';
...
free(out);
*/
std::wstring w = wstring.str();
size_t size = w.size() + 1;
wchar_t* out = new wchar_t[size];
std::memcpy(out, w.c_str(), size * sizeof(wchar_t));
...
delete[] out;
/*
std::wstring w = wstring.str();
size_t size = (w.size() + 1) * sizeof(wchar_t);
wchar_t* out = (wchar_t*) malloc(size);
std::memcpy(out, w.c_str(), size);
...
free(out);
*/
但是,无论哪种方式,因为 str()
returns 一个 std::wstring
开始,你最好坚持使用 std::wstring
而不是使用 wchar_t*
全部:
std::wstring out = wstring.str();
如果你需要 (const) wchar_t*
,你可以使用 out.c_str()
或 out.data()
,例如当将 out
传递给采用空终止字符串的 C 风格函数时指针。
假设需要将字符串传递给期望 free
它的函数,您可以使用 malloc
和 memcpy
:
auto const ws = wstring.str();
auto const ptr = std::malloc(sizeof wchar_t * (ws.size() + 1));
std::memcpy(ptr, ws.c_str(), sizeof wchar_t * (ws.size() + 1));
// pass ptr to another function, or std::free(ptr)
+ 1
是考虑空终止符,size()
中没有。
传统的方法是在你的程序中有一个配置系统,告诉你平台有什么和没有什么:
在一些专门用于可移植性的源文件中,您有:
#if !HAVE_WCSDUP
wchar_t *wcsdup(const wchar_t *orig)
{
#if HAVE_MICROSOFT_WCSDUP
return _wcsdup(orig);
#else
size_t nwch = wcslen(orig) + 1;
wchar_t *copy = wmalloc(nwch);
if (copy)
wmemcpy(copy, orig, nwch);
return copy;
#endif
}
#endif
在一些头文件(也包括在上面)中,你有这个:
#if !HAVE_WSCDUP
extern "C" wchar_t wcsdup(const wchar_t *);
#endif
提供缺少的声明。一种可能的方法也是这样。在头文件中,你做:
#if HAVE_WCSDUP
// nothing to provide
#elif HAVE_MICROSOFT_WCSDUP
// just alias to the Microsoft one via #define
#define wcsdup _wcsdup
#else
// declare ours: provided in portability.cc
extern "C" wchar_t wcsdup(const wchar_t *);
#endif
然后在portability.cc
:
#if !HAVE_WCSDUP && !HAVE_MICROSOFT_WCSDUP
wchar_t *wcsdup(const wchar_t *orig)
{
size_t nwch = wcslen(orig) + 1;
wchar_t *copy = wmalloc(nwch);
if (copy)
wmemcpy(copy, orig, nwch);
return copy;
}
#endif
您需要围绕您的程序构建配置系统来提供这些 HAVE_
常量的值。在某些系统上,shell 脚本可以检查环境并将它们扔到 config.h
中。对于某些系统,您可以使用固定配置;例如在 Windows 上构建的配置步骤可能包括将手动维护的 config-msvc.h
复制到 config.h
。在 config-msvc.h
你有:
#define HAVE_MICROSOFT_WCSDUP 1
我假设您需要一个 malloc
重复的字符串,因为与一些消耗一个的 API 进行通信。因此,在我的回答中,我没有自以为是地使用 C++ 库功能来解决问题。
然而,在 C++ 代码中,我们可能应该将 C 函数称为 std::wcslen
等等。或者 portability.cc
可以只是 portability.c
,如果它提供缺少的 C 函数。