将窄字符串插入到 std::basic_ostream<wchar_t>
Inserting narrow character string to std::basic_ostream<wchar_t>
根据cppref, std::basic_ostream<wchar_t>
接收const char*
, operator <<
过载。似乎转换操作只是将每个char
拓宽为wchar_t
。也就是说,转换(插入)的宽字符的数量等于窄字符的数量。问题来了。狭窄的字符串可能编码国际字符,例如使用GB2312编码的中文字符。进一步假设sizeof(wchar_t)
是2
并使用UTF16编码。那么这种简单的字符转换方法应该如何工作呢?
我刚刚检查了Visual Studio 2015,你是对的。char
s只加宽到wchar_t
s,没有任何转换。在我看来,你将不得不自己将窄字符串转换为宽字符串。有几种方法可以做到这一点,其中一些已经被建议过了。
在这里,我建议您可以使用纯c++工具来完成它,假设您的c++编译器和标准库足够完整(Visual Studio,或Linux上的GCC(仅在那里)):
void clear_mbstate (std::mbstate_t & mbs);
void
towstring_internal (std::wstring & outstr, const char * src, std::size_t size,
std::locale const & loc)
{
if (size == 0)
{
outstr.clear ();
return;
}
typedef std::codecvt<wchar_t, char, std::mbstate_t> CodeCvt;
const CodeCvt & cdcvt = std::use_facet<CodeCvt>(loc);
std::mbstate_t state;
clear_mbstate (state);
char const * from_first = src;
std::size_t const from_size = size;
char const * const from_last = from_first + from_size;
char const * from_next = from_first;
std::vector<wchar_t> dest (from_size);
wchar_t * to_first = &dest.front ();
std::size_t to_size = dest.size ();
wchar_t * to_last = to_first + to_size;
wchar_t * to_next = to_first;
CodeCvt::result result;
std::size_t converted = 0;
while (true)
{
result = cdcvt.in (
state, from_first, from_last,
from_next, to_first, to_last,
to_next);
// XXX: Even if only half of the input has been converted the
// in() method returns CodeCvt::ok. I think it should return
// CodeCvt::partial.
if ((result == CodeCvt::partial || result == CodeCvt::ok)
&& from_next != from_last)
{
to_size = dest.size () * 2;
dest.resize (to_size);
converted = to_next - to_first;
to_first = &dest.front ();
to_last = to_first + to_size;
to_next = to_first + converted;
continue;
}
else if (result == CodeCvt::ok && from_next == from_last)
break;
else if (result == CodeCvt::error
&& to_next != to_last && from_next != from_last)
{
clear_mbstate (state);
++from_next;
from_first = from_next;
*to_next = L'?';
++to_next;
to_first = to_next;
}
else
break;
}
converted = to_next - &dest[0];
outstr.assign (dest.begin (), dest.begin () + converted);
}
void
clear_mbstate (std::mbstate_t & mbs)
{
// Initialize/clear mbstate_t type.
// XXX: This is just a hack that works. The shape of mbstate_t varies
// from single unsigned to char[128]. Without some sort of initialization
// the codecvt::in/out methods randomly fail because the initial state is
// random/invalid.
std::memset (&mbs, 0, sizeof (std::mbstate_t));
}
这个函数是log4cplus库的一部分,它可以工作。它使用codecvt
面来进行转换。你必须给它适当的设置locale
。
Visual studio可能会在为GB2312适当设置区域设置时出现问题。您可能必须使用_setmbcp()
才能使其工作。有关详细信息,请参见"Visual Studio 2015中的双字节字符序列转换问题"。
相关文章:
- MacOS通过在莫哈韦"wchar.h"下破碎的自制啤酒发出叮当声
- EASTL矢量<向量<int>>连续的
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- 'const char*'和'WCHAR*'
- 为什么需要与 WCHAR 相关的代码处理
- 无法使用 mingw-w64 g++ 编译:找不到 <wchar.h>
- 无法将参数 1 从 WCHAR 转换为常量字符 *
- 无法使用 swprintf 在 WCHAR* 中打印字符*
- -fshort-wchar 和 std::wstring - 分段错误
- 我应该使用 wchar 还是 char 来加密?
- 【MacOSX 10.15.1】使用 odb 生成数据库,致命错误:wchar.h:没有这样的文件或目录 #include < wchar.h>
- 如何在 C++ 中的 wcstok 中使用常量 WCHAR* 变量?
- 将字符串文本常量定义为 char const* 和 wchar const*
- 比较嵌套 for 循环中的两个 wchar 数组?
- wchar 模式下 pugixml 的链接错误
- strcmp 错误'WCHAR [260]' 'const char *'
- 'Cannot add two pointers'添加带有 WCHAR 的 LPCWSTR
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 如何将CString转换为使用WCHAR的Windows API和自定义函数?
- C 字符串比较“祝您好运”&gt;“再见”